2017-02-21 44 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; 
} 

Я скомпилировать/запустить его так:

Compile + Run 1:

$ g++ macro1.cpp 

$ ./a.out 

start 

debug line 1 

debug line 2 

debug line 3 

end 
$ 

Compile + Run 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

Препроцессор глупее, чем вы думаете. Он просто включает в себя, затем просматривает файл сверху вниз. Посмотрите на состояние своего '.cpp' после' #include "macro1.h" ', и вы увидите, что происходит. –

ответ

1

Похоже, вы не понимаете, как работает препроцессор. Вот хороший, быстрый учебник: http://www.cplusplus.com/doc/tutorial/preprocessor/

Что касается вашей конкретной проблемы: макрос DEBUG определяется только один раз, основываясь на определении макроса NO_DEBUG. Как только препроцессор решает, какое определение использовать, вы больше не можете изменять определение макроса DEBUG. Вы пытаетесь использовать # unset/# define для достижения этого, но, как отметил @Baum mit Augen, препроцессор - это просто механизм замены текста и очень «тупой». Это не делает ничего необычного, кроме замены текста.

Таким образом, к тому моменту, когда вы используете свои фактические макросы DEBUG, у них есть только одно определение, основанное на NO_DEBUG, и вы либо получите всю печать, либо ничего не распечатаете, как вы видели.