2015-08-05 3 views
1

Я хочу использовать макрос, определенный в разных заголовочных файлах с тем же именем и разными реализациями. У меня есть два файла заголовка h1.h и h2.h. В первом файле заголовка я определил:Неопределенный макрос, определенный дважды

#define PRINT printf(" hi , macro 1\n"); 

и во втором файле заголовка

#define PRINT printf(" hi , macro 2\n"); 

в main(), когда я пытаюсь использовать PRINT она печатается в зависимости от порядка включения. я нашел несколько подобных проблем, и они использовали обертку, включив первый файл заголовка, то определение линейного способа:

inline void print1() { 
     PRINT(); 
} 

, а затем PRINT и не определенную в том числе второго файла заголовок. В main(), когда я вызываю print1() и PRINT, я получил вывод от них обоих. Мой недостающий момент заключается в том, как после того, как мы определили PRINT из первого файла заголовка, который мы все еще можем его использовать, другими словами, что происходит, когда мы вызываем его внутри встроенной функции? Составил ли компилятор значение PRINT и назначил его функции и каким-то образом сохранил функцию?

+1

Сюрприз сюрприз, вы используете препроцессор MACRO ... :-) –

ответ

3

Если я правильно понимаю, что-то подобное происходит:

#include "h1.h" // defines PRINT: printf(" hi , macro 1\n"); 

inline void print1(){ 
    PRINT(); 
} 

#undef PRINT 

#include "h2.h" // defines PRINT: printf(" hi , macro 2\n"); 

ничего странного не происходит, хотя. Предпроцессорные подстановки PRINT внутри встроенной функции до того, как она не определена. Таким образом, в результате код (вы можете увидеть это при компиляции с -E флагом для GCC), он становится этим:

// contents of h1.h... 

inline void print1(){ 
    printf(" hi , macro 1\n"); 
} 

// contents of h2.h... 

#define г макросы сохраняются только на время предварительной обработки, и подставляются как идет предварительный процессор. Подобно переменным в обычном программировании, если вы повторно назначили его, препроцессор будет просто использовать новое значение для следующих случаев.

+0

большое спасибо. –

1

Это работает, потому что во время компиляции предварительный процессор достигает PRINT() вызова в print1, вычисляет макрос и заменяет его текущим значением. Затем, если я правильно понял, позже (в следующих строках) вы переопределите или определите PRINT (будь то включение другого заголовка), то любая дополнительная ссылка на него заставит препроцессор снова заменить его текущим значением (что теперь разные), поэтому вы получаете 2 отличных поведения, называющих «тот же» макрос.

+0

большое спасибо, теперь понятно. –

Смежные вопросы