後勝ち
今日、今年一番のやらかしちゃったな不具合が発覚orz
C++で複数の同じ名前のマクロが定義されていた場合、後勝ちなんですね。
// a.h #ifndef A_H_INCLUDED #define A_H_INCLUDED #define ARRAY_NUM 100 #endif // A_H_INCLUDED
// hoge/a.h #define ARRAY_NUM 20
// c.h #ifndef C_H_INCLUDED #define C_H_INCLUDED static int anArray[ ARRAY_NUM ] = { 0 }; #endif // C_H_INCLUDED
// main.cpp #include "a.h" #include "hoge/a.h" #include "c.h" #include <stdio.h> template< typename T, size_t N > size_t NUMOFARRAY( T (&)[ N ] ){ return N; } void main() { fprintf( stdout, "NUM=%d\n", NUMOFARRAY( anArray ) ); (void)::fgetc( stdin ); }
hoge/a.h(2) : warning C4005: 'ARRAY_NUM' : マクロが再定義されました。 a.h(4) : 'ARRAY_NUM' の前の定義を確認してください
こんなwarningが出ます。このプログラムを実行すると、「NUM=20」となります。
「a.h」と「hoge/a.h」の順番を入れ替えると「NUM=100」となりました。
このようなプログラムに対し、2ヶ月前の自分はwarningうぜぇぇと思い「hoge/a.h」をこんな風に修正していました。
// hoge/a.h #ifndef A_H_INCLUDED #define ARRAY_NUM 20 #endif // A_H_INCLUDED
当然結果は「NUM=100」となります。
こんな修正をした理由は、単純に「ARRAY_NUM」がmain.cppで使われているかどうかを見て、使ってないから良いかと思ってしまった次第で、「anArray」の利用状況について全く観ていませんでしたorz
反省点としては色々ありますが、
-
- 修正する必要がない部分をいじった
- いじったのにちゃんと確認しなかった
- 後勝ちルールを知らなかった
- ソースを追い切れていなかった
もうため息と不具合しかでませんが猛省します。こんな事ばかりやってるから残業が増えてるの鴨な。