C 言語 マクロ講座 地獄編2007年03月25日 11時36分13秒

定義されているマクロを打ち消すのに #undef が使える。

% cat undef.c 
#define BLOG "http://uyota.asablo.jp/blog/"

#undef BLOG

BLOG
% gcc -E undef.c
# 1 "undef.c"
# 1 ""
# 1 ""
# 1 "undef.c"




BLOG

自動生成されたファイルや、何らかの理由で明示的にマクロが定義されていないことを示すのに使われているのが主に見る使われ方だ。

もし、#undef が #define と対になって使われているようだったら、危険信号だ。恐らく、既に何かが破綻しているのだろう。

なぜだかは、以下の二つの例を見れば分かるだろう。


% cat true.c 
#define TRUE 0
#define TRUE 0
% gcc -E true.c 
# 1 "true.c"
# 1 ""
# 1 ""
# 1 "true.c


% cat false.c 
#define FALSE 1
#define FALSE 0
% gcc -E false.c 
# 1 "false.c"
# 1 ""
# 1 ""
# 1 "false.c"
false.c:2:1: warning: "FALSE" redefined
false.c:1:1: warning: this is the location of the previous definition

マクロは記号定数としても使われる。定数なので、一箇所にのみで定義されているべきだ。何らかの手違いで、二箇所で定義されてしまうことも目にしたこともあるが、見つけたらすぐに直してしまうに限る。

以前に一つのアプリケーションの中で以下のようなヘッダファイルを見たことがある。


% cat one.h 
#ifndef ONE_H
#define ONE_H

#undef TRUE
#define TRUE 1

#undef FALSE
#define

#endif
% cat two.h 
#ifndef TWO_H
#define TWO_H

#undef TRUE
#define TRUE 0

#undef FALSE
#define FALSE 1

#endif

これ以外にもたくさんのマクロが定義されていたが、同じマクロに場所によって違う値を割り当てているのだ。 これでは、ファイルの読込順により、動作が変わってしまう。十年以上も少なくても期待した動作はしていたとのことなので、偶然だとは言え内部的には変更を加えない限りは何とか動作していた。もちろん、このプログラムに変更を加えるのは不可能だった。ヘッダファイルに手を出したり、TRUE や FALSE を扱う関数を追加すると 、異常な動作をするようになるのだから。

マクロは同一の定義があった場合には、エラーにはならない。わざわざ、#undef を置くのは、何らかの理由があった筈だ。そのため、 #undef と #define がヘッダファイルに続いているのは、明らかに地獄への入口を示しているのだ。もちろん、その理由は、同じマクロが既に違う値で定義されていた以外にはない。

前回次回