C++でerror: assignment of read-only variable が出る原因と直し方
constを付けて宣言した変数に、あとから値を代入しようとしたときに出るエラーです。constは「この変数は初期化後に変更しない」という約束をコンパイラに伝えるものです。
エラーメッセージの読み方
main.cpp:4:11: error: assignment of read-only variable 'limit'
main.cpp- ファイル名
4- 行番号
11- 列番号 — この位置でg++が構文解析に失敗しました
assignment of read-only variable 'limit'- 内容 — 期待していたもの、または受け付けられなかったもの
このエラーが出る典型パターン
パターン1
1 #include <iostream> 2 int main() { 3 const int limit = 100; 4 limit = 200; ^ 5 std::cout << limit << std::endl; 6 return 0; 7 }
constを付けた変数はコンパイラが「変更しない」という約束を強制します。値を変えたいなら、別のconstでない変数を新しく用意します。
直し方: limit を int limit2 にします。
パターン2
1 #include <iostream> 2 int main() { 3 const int maxSpeed = 60; 4 maxSpeed = 80; ^ 5 std::cout << maxSpeed << std::endl; 6 return 0; 7 }
maxSpeedはconstとして宣言されているため、その名前への代入はコンパイル時に拒否されます。
直し方: maxSpeed を int newSpeed にします。
パターン3
1 #include <iostream> 2 int main() { 3 const int taxRate = 10; 4 taxRate = 20; ^ 5 std::cout << taxRate << std::endl; 6 return 0; 7 }
「constは目印にすぎない」というのは誤解で、実際にコンパイラがチェックする言語機能です。
直し方: taxRate を int newRate にします。
パターン4
1 #include <iostream> 2 int main() { 3 const int cap = 50; 4 cap = 100; ^ 5 std::cout << cap << std::endl; 6 return 0; 7 }
constの変数への代入はコンパイラが必ず拒否します。値を変えたい場合は別の変数を用意します。
直し方: cap を int cap2 にします。
パターン5
1 #include <iostream> 2 int main() { 3 const double rate = 0.05; 4 rate = 0.1; ^ 5 std::cout << rate << std::endl; 6 return 0; 7 }
double型のconst変数でも同様です。名前への代入はコンパイル時に検出されます。
直し方: rate を double rate2 にします。
よくある誤解
「constは単なる目印(コメント代わり)」というのは誤解です。C++のconstはコンパイラが実際にチェックする言語機能で、違反があればコンパイルそのものが止まります。
実務での勘所
constの制約には、意図的な例外を認める仕組みも用意されています。mutableと宣言したメンバ変数は、そのオブジェクトがconstとして扱われている文脈でも変更できます。典型的な使い道は、計算コストの高い値を初めて必要になったときだけ計算してキャッシュしておく、という「論理的には不変だが内部実装としては書き換えが必要」な場面です。むやみに使うと本来のconstの意図が崩れるため、本当に必要な場面に限って使うべき機能です。