redefのウォーニングは何を説明しているでしょうか。
テストプログラムを書きます。main.c
#define TEST_MACRO (1)#include <stdio.h>
int main()
{
printf( "TEST_MACRO is %d \n", TEST_MACRO );
return 0;
}
$ gcc -o test1 main.c $ ./test1 TEST_MACRO is 1
マクロをコマンドラインで指定しても、、
$ gcc -o test2 -DTEST_MACRO=2 main.c
main.c:2:1: warning: "TEST_MACRO" redefined
<command line>:6:1: warning: this is the location of the previous definition
$ ./test2
TEST_MACRO is 1
ウォーニングを良く見てください。
<command line>:6:1: warning: this is the location of the previous definition
<コマンドライン>:6行目1桁目 警告:これは前に定義された場所です
プログラム中の#defineマクロ定数を-Dオプション指定で上書きすることはできないのです。
プログラムを変えてみれば、すぐに分かることです。
#define TEST_MACRO (1)
#define TEST_MACRO (2)#include <stdio.h>
int main()
{
printf( "TEST_MACRO is %d \n", TEST_MACRO );
return 0;
}
$ gcc -o test3 main.c main.c:2:1: warning: "TEST_MACRO" redefined main.c:1:1: warning: this is the location of the previous definitionyasuda@R3 ~/src
$ ./test3
TEST_MACRO is 2
後の定義の値が使われます。これは処理系依存でgccのオプション指定の仕方次第なのかもしれません。それでもこれらの短い書き捨てプログラムを書けば良いだけです。暗記は必要ありません。しかし勝手な思い込みは避けなければなりません。
また、redefを利用したトリック実装も避けなければなりません。
異なった値で2重定義をおこなえば、#includeを書く順序で結果が異なるからです。
redefはエラーとできるなら、そうすべきでしょう。
ちなみに#defineを文字列置換だと勘違いしている人が世の中には多数居ます。
実際にはプリプロセッサのパーサで解釈された文脈の中でのみ有効です。
例えばこんなプログラム断片。
#define FUNNY_MACRO (0x55aa)int main()
{
printf( "FUNNY_MACRO is used by strange people.\n" );
}
・・・
この文字列定数が置換されないのは言うまでもありません。
どんな処理系でも細かい話はいくらでもあります。ですが、覚えておくべきことは少ないです。少しでも不安なのであれば、試してみることがもっとも重要です。
コメント