error: assignment of read-only variable の原因と直し方
constをつけて宣言した変数に、後から値を代入しようとしたときに出るエラーです。constは「一度決めたら変更不可」を意味します。
エラーメッセージの読み方
main.c:5:9: error: assignment of read-only variable 'max'
main.c- ファイル名
5- 行番号
9- 列番号 — この位置でgccが構文解析に失敗しました
assignment of read-only variable 'max'- 内容 — 期待していたもの、または受け付けられなかったもの
このエラーが出る典型パターン
パターン1
1 #include <stdio.h> 2 3 int main(void) { 4 const int max = 100; 5 max = 200; ^ 6 printf("%d\n", max); 7 return 0; 8 }
constを付けた変数は宣言後に変更できません。値を書き換えたい場合は、別の変数を用意します。
直し方: max を int limit にします。
パターン2
1 #include <stdio.h> 2 3 int main(void) { 4 const int total = 50; 5 total = 10; ^ 6 printf("%d\n", total); 7 return 0; 8 }
constの変数に直接代入しようとすると、コンパイル時にすぐエラーとして検出されます。実行時まで気づかないバグを未然に防げます。
直し方: total を int extra にします。
パターン3
1 #include <stdio.h> 2 3 int main(void) { 4 const double rate = 0.05; 5 rate = 0.1; ^ 6 printf("%.2f\n", rate); 7 return 0; 8 }
double型のconst変数でも同様です。一度決めた値を変更したくない場合にconstは効果を発揮します。
直し方: rate を double bonus にします。
パターン4
1 #include <stdio.h> 2 3 int main(void) { 4 const int limit = 10; 5 limit = 20; ^ 6 printf("%d\n", limit); 7 return 0; 8 }
constの変数に直接代入しようとすると、コンパイル時にエラーとして検出されます。
直し方: limit を int cap にします。
パターン5
1 #include <stdio.h> 2 3 int main(void) { 4 const double tax = 0.08; 5 tax = 0.2; ^ 6 printf("%.2f\n", tax); 7 return 0; 8 }
double型のconst変数でも同様です。値を変えたい場合は別の変数を用意します。
直し方: tax を double discount にします。
よくある誤解
constは単なる「初期値のヒント」ではなく、コンパイラが強制するルールです。定数として扱いたい値にconstをつけておくと、うっかり書き換えてしまうミスをコンパイル時に検出できます。
実務での勘所
関数の引数にconstを付ける最大の実用的な価値は、呼び出す側への約束です。void print(const char *s)のように書けば、「この関数はsの指す中身を変更しない」という契約を、コンパイラにチェックさせながら明示できます。呼び出す側は、この関数に渡した後もデータが書き換えられないと安心して呼べます。標準ライブラリの多くの関数(strlenやprintfの書式文字列など、読むだけで書き換えないもの)がconstを付けているのはこの理由です。