2017-02-21 104 views
1

這裏是我的代碼:宏觀控制DEBUG

macro1.h

#ifndef NO_DEBUG 
#define DEBUG(arg) cout<<endl<<arg<<endl 
#else 
#define DEBUG(arg) 
#endif 

macro1.cpp

#include <iostream> 
#include "macro1.h" 
using namespace std; 
int main() 
{ 
    cout<<endl<<"start"<<endl; 
    DEBUG("debug line 1"); 
    #undef NO_DEBUG 
    DEBUG("debug line 2"); 
    #define NO_DEBUG 
    DEBUG("debug line 3"); 
    cout<<endl<<"end"<<endl; 
    return 0; 
} 

我編譯/像這樣運行:

編譯+運行1:

$ g++ macro1.cpp 

$ ./a.out 

start 

debug line 1 

debug line 2 

debug line 3 

end 
$ 

編譯+運行2:

$ g++ macro1.cpp -DNO_DEBUG 

$ ./a.out 

start 

end 
$ 

但是,這並不是我所期待的, 在第一次運行,因爲NO_DEBUG沒有定義它必須打印:

start 

debug line 1 

debug line 2 

end 

在第二輪中,我們正在通過命令行定義宏,所以它必須打印:

start 

debug line 2 

end 

所以有人可以告訴我發生了什麼事 在這?

我只使用預處理功能,所以它應該正常工作?

+0

只有在'#include「macro1.h」'重點定義的宏定義。 –

+0

但是.h文件的內容也可以複製粘貼到.cpp文件中,並且.cpp的預處理仍然需要完成,對吧?那麼爲什麼只有直到'#include「macro1.h」'重要? – Sumit

+0

預處理器比您想象的要笨重。它只是包含,然後從上到下走文件。在'#include「macro1.h」'後查看'.cpp'的狀態,你會看到發生了什麼。 –

回答

1

看起來你錯誤地理解了預處理器的工作原理。下面是一個很好的快速教程:http://www.cplusplus.com/doc/tutorial/preprocessor/

至於你的特定問題:DEBUG宏只能根據NO_DEBUG宏定義定義一次。一旦預處理器決定使用哪個定義,就不能再改變DEBUG宏的定義。您正在嘗試使用#unset /#定義來完成此操作,但正如@Baum mit Augen所指出的那樣,預處理器僅僅是一個文本替換引擎,而且非常「愚蠢」。除了替換文字之外,它沒有什麼特別之處。因此,當你看到你正在使用的實際DEBUG宏時,它們只有一個基於NO_DEBUG的定義,你將得到所有的打印或沒有打印,就像你看到的那樣。