事の起こり
C++のconst修飾子を勉強してみました!!
少しややこしい仕様になっているのでの忘備録としてメモします。
環境
・IDE:xcode
・コンパイラ:Default compiler(AppleのClangですね。)
・言語:C++ 14
問題
「とりあえず値変えたくない時は、適当にconst付けておけば良いや」と甘い考えを持っていたら、次の2つのエラーに苦しめられてしまいました。
1.Cannot assign to variable 'ptr1' with const-qualified type 'int *const'
2.Read-only variable is not assignable
問題のコードはこちらです。皆さんは原因が分かりますか?
int main(int argc, const char * argv[]) {
int value = 128;
int* const ptr1 = &value;
ptr1 = nullptr;//ここで1番のエラー
*ptr1 = 5;
int const* ptr2 = &value;
ptr2 = nullptr;
*ptr2 = 5;//ここで2番のエラー
return 0;
}
原因
実はC/C++において、「int* const」と「int const*」は別の意味を持っています。
・「int* const」はその変数(ptr1)のアドレスが不変であること示す。(アドレス変更NG)
・「int const*」はその変数(ptr2)の値が不変であることを示す。(値変更NG)
今回の例では、int* constで宣言したアドレス不変のptr1にnullptrを代入しようとして1番のエラーが、int const*で宣言した値不変のptr2に5を代入しようとして2番のエラーが発生していたようです。
ちなみに、アドレスも値も変更不可としたい場合は、
const int* const 変数名
としてやれば良いそうです。
まとめ
正直、分かりづらいですよね・・・。しかし、constが右側にかかることを意識して、次のように読み方を覚えてしまえば楽!!(なのかも)。読み方のポイントは「constが右側にかかる」という点です!!
(例1) int* const 変数名
constは右側にかかる。constがかかるのは「変数名」なので、その変数が示すもの、すなわち「アドレス」が不変であると解釈。
(例2) int const* 変数名
constは右側にかかる。constがかかるのは「* 変数名」なので、その変数のアドレスが示すものすなわち、「値」が不変であると解釈。
(例3) const int* const 変数名
2番目のconstは「変数名」にかかる。すなわち、その変数が示すもの「アドレス」が不変である。さらに、1番目のconstは「* const 変数名」にかかるのでその変数のアドレスが示すもの「値」が不変であると解釈。
以上。