巨集定義與列舉定義衝突錯誤
我在一個檔案 displaynumber.h 中定義了一個列舉:
class CDisplayNumber : public CStatic
{
DECLARE_DYNAMIC(CDisplayNumber)
public:
CDisplayNumber();
virtual ~CDisplayNumber();
enum NUMBER_COLOR
{
BLACK,
GREEN,
RED,
YELLOW
};
......
};
在編譯時總是提示:
1>d:/works/meet/commcontrol/displaynumber.h(18) : error C2143: syntax error : missing '}' before '('
1>d:/works/meet/commcontrol/displaynumber.h(22) : error C2143: syntax error : missing ';' before '}'
1>d:/works/meet/commcontrol/displaynumber.h(22) : error C2238: unexpected token(s) preceding ';'
1>d:/works/meet/commcontrol/displaynumber.h(24) : error C2065: 'NUMBER_COLOR' : undeclared identifier
經過查詢,另一個檔案 graph.h 中定義了:
#define RED RGB(255,0,0)
#define GREEN RGB(0,255,0)
#define BLUE RGB(0,0,255)
#define YELLOW RGB(255,255,0)
#define ORANGE RGB(255,153,51)
#define HOT_PINK RGB(255,51,153)
#define PURPLE RGB(153,0,204)
#define CYAN RGB(0,255,255)
#define BLACK RGB(0,0,0)
且一個cpp檔案隱式包含:
#include "graph.h"
#include "displaynumber.h"
把這個包含關係互換,編譯就不再出錯。
總結:
這裡因為編譯在編譯的時候,先遇到巨集定義#define BLACK RGB(0,0,0) ,然後繼續編譯遇到列舉型別中的 BLACK ,它直接把BLACK 替換成了RGB(0,0,0)所以成了
enum NUMBER_COLOR
{
RGB(0,0,0),
GREEN,
RED,
YELLOW
};
這樣,編譯器就發出了錯誤警告。
幸運的是這個編譯器發現了錯誤。
假如,巨集 BLACK 定義成一個字元,例如:、
#define BLACK b
則編譯器不會發出錯誤,繼續編譯成功,但實際上,NUMBER_COLOR中的常量BLACK,就隱式的改成了 b。這樣就為程式埋下了隱患。而這個隱患一但發生,是很難查詢的錯誤。