error: invalid type argument of unary '*'(関数ポインタ呼び出しの優先順位)
*fp(a, b)と書くと、関数呼び出し()の方が間接参照*より優先順位が高いため、fp(a, b)を先に呼び出してからその戻り値に*を適用しようとしてしまいます。
エラーメッセージの読み方
main.c:7:18: error: invalid type argument of unary '*' (have 'int')
main.c- ファイル名
7- 行番号
18- 列番号 — この位置でgccが構文解析に失敗しました
invalid type argument of unary '*' (have 'int')- 内容 — 期待していたもの、または受け付けられなかったもの
このエラーが出る典型パターン
パターン1
1 #include <stdio.h> 2 3 int add(int a, int b) { return a + b; } 4 5 int main(void) { 6 int (*fp)(int, int) = add; 7 int result = *fp(2, 3) ; ^ 8 printf("%d\n", result); 9 return 0; 10 }
main.c:7:18: error: invalid type argument of unary '*' (have 'int')
()は*より優先順位が高いため、*fp(2, 3)はfp(2, 3)を先に呼び出そうとします。fpは変数(関数ポインタ)であって関数ではないため、呼び出せずエラーになります。(*fp)(2, 3)のように括弧でfpを間接参照してから呼び出す必要があります。
直し方: *fp(2, 3) を (*fp)(2, 3) にします。
広告
広告スロット(未設定)
パターン2
1 #include <stdio.h> 2 3 int multiply(int a, int b) { return a * b; } 4 5 int main(void) { 6 int (*fp)(int, int) = multiply; 7 int result = *fp(4, 5) ; ^ 8 printf("%d\n", result); 9 return 0; 10 }
main.c:7:18: error: invalid type argument of unary '*' (have 'int')
関数ポインタ経由の呼び出しは(*関数ポインタ名)(引数)という形が正しい書き方です。
直し方: *fp(4, 5) を (*fp)(4, 5) にします。
パターン3
1 #include <stdio.h> 2 3 int subtract(int a, int b) { return a - b; } 4 5 int main(void) { 6 int (*fp)(int, int) = subtract; 7 int result = *fp(10, 3) ; ^ 8 printf("%d\n", result); 9 return 0; 10 }
main.c:7:18: error: invalid type argument of unary '*' (have 'int')
実際には多くのコンパイラがfp(...)(括弧無しの間接参照)も許容しますが、*fp(...)は完全に別の意味になるため注意が必要です。
直し方: *fp(10, 3) を (*fp)(10, 3) にします。
よくある誤解
関数ポインタを「呼び出す」つもりで*fp(a, b)と書いても、Cはfpそのものを関数として呼ぼうとはしません。まずfp(a, b)を評価しようとするため、意図と違う解釈になります。関数ポインタ経由で呼び出すときは(*fp)(a, b)と括弧でまとめるのが安全です。
まとめ
error: invalid type argument of unary '*'(関数ポインタ呼び出しの優先順位)は上級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。