桜、抹茶、白、日記

名古屋市在住のC++使いのcoderの日記だったもの。

後勝ち

今日、今年一番のやらかしちゃったな不具合が発覚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 );
}

こんなプログラムをVC++コンパイルすると、

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
反省点としては色々ありますが、

    1. 修正する必要がない部分をいじった
    2. いじったのにちゃんと確認しなかった
    3. 後勝ちルールを知らなかった
    4. ソースを追い切れていなかった

もうため息と不具合しかでませんが猛省します。こんな事ばかりやってるから残業が増えてるの鴨な。