error: invalid conversion from 'int*' to 'int' の原因と直し方
アドレス演算子&で得たポインタを、参照や普通の変数と混同して代入しようとしたときに出るエラーです。&xはint*型であり、int型の変数にそのまま代入することはできません。
エラーメッセージの読み方
main.cpp:4:15: error: invalid conversion from 'int*' to 'int' [-fpermissive]
main.cpp- ファイル名
4- 行番号
15- 列番号 — この位置でg++が構文解析に失敗しました
invalid conversion from 'int*' to 'int' [-fpermissive]- 内容 — 期待していたもの、または受け付けられなかったもの
このエラーが出る典型パターン
パターン1
1 #include <iostream> 2 int main() { 3 int x = 5; 4 int ref = & x; ^ 5 std::cout << ref << std::endl; 6 return 0; 7 }
&xはint*型(xのアドレス)です。int型の変数にそのまま代入することはできません。ここでは単に値をコピーしたいだけなので&は不要です。
直し方: & を (空) にします。
パターン2
1 #include <iostream> 2 int main() { 3 int score = 90; 4 int copy = & score; ^ 5 std::cout << copy << std::endl; 6 return 0; 7 }
「参照を使えばアドレスが取れる」という思い込みから&を付けてしまうミスです。値をコピーするだけなら&は要りません。
直し方: & を (空) にします。
パターン3
1 #include <iostream> 2 int main() { 3 int total = 42; 4 int value = & total; ^ 5 std::cout << value << std::endl; 6 return 0; 7 }
g++は「possible fix: dereference with '*'」とも提案しますが、それは*totalにすればポインタの中身が読めるという意味で、今回のように単純代入したい場合は&自体を消すのが正しい直し方です。
直し方: & を (空) にします。
パターン4
1 #include <iostream> 2 int main() { 3 int n = 8; 4 int result = & n; ^ 5 std::cout << result << std::endl; 6 return 0; 7 }
&nはint*型(アドレス)です。int型の変数へそのまま代入することはできません。
直し方: & を (空) にします。
パターン5
1 #include <iostream> 2 int main() { 3 int level = 3; 4 int lv = & level; ^ 5 std::cout << lv << std::endl; 6 return 0; 7 }
値をコピーしたいだけなら&は不要です。付けるとアドレスを代入しようとしてエラーになります。
直し方: & を (空) にします。
よくある誤解
「参照もポインタも結局アドレスを扱うものだから同じ」というのは誤解です。参照(int&)は既存の変数の別名であり、宣言時に&を書きますが、それは「アドレスを代入する」のではなく「参照として初期化する」という別の文法です。
実務での勘所
参照とポインタの違いは構文だけでなく、できることの範囲にも表れます。参照は宣言と同時に初期化しなければならず、一度ある変数を参照したら別の変数を指すように後から変更することはできません。ポインタは宣言後に自由に指し先を変更でき、どこも指さない状態(nullptr)も表現できますが、参照は(意図的に未定義動作を起こさない限り)常に有効な何かを指していることが前提です。この制約の分だけ、参照はポインタより安全に使える場面が多くなります。