第6回 コンパイラ実装会で出た話題です。
以下のコードがエラーになります。なぜ?
test.cpp
#include <stdlib.h> int main(void) { void *p = malloc(100); *(void **)&p[10] = reinterpret_cast<void *>(free); return 0; }
コンパイル結果
$ g++ test.cpp test.cpp: In function 'int main()': test.cpp:5:20: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith] test.cpp:5:20: error: 'void*' is not a pointer-to-object type
voidは実体がないのでvoid*はdereferenceできません。void型の変数がエラーになるのと同じ理屈です。
test.cpp
int main(void) { void a; return 0; }
コンパイル結果
$ g++ test.cpp test.cpp: In function 'int main()': test.cpp:4:10: error: variable or field 'a' declared void
バイト単位で位置を取りたいなら、char*にキャストすればうまくいきます。
#include <stdlib.h> int main(void) { char *p = reinterpret_cast<char *>(malloc(100)); *(void **)&p[10] = reinterpret_cast<void *>(free); return 0; }
なぜnewを使わずにmalloc()なのか?と思われるかもしれません。実際はmmap()を使っていましたが、例として単純化するためmalloc()に置き換えて説明しました。