Когда раскрывается макрос "__FILE__"?
Я делаю в хедере lib.h
#define TEST __FILE__
а потом в main.cpp
:
#include "lib.h"
std::cout << TEST;
И мне печатает имя main.cpp
. Я бы ожидал файл lib.h
. В каком порядке раскрываются инклюды и прочие макросы?
Ответы (2 шт):
Автор решения: Stanislav Volodarskiy
→ Ссылка
Макросы раскрываются в момент подстановки. Если бы вы использовали макрос внутри lib.h, вы бы получили ожидаемое:
$ cat temp.h #define TEST __FILE__ void f() { puts(TEST); } $ cat temp.c #include <stdio.h> #include <temp.h> void g() { puts(TEST); } int main() { f(); g(); } $ gcc -I. temp.c $ ./a.out ./temp.h temp.c
Автор решения: user7860670
→ Ссылка
В С/C++ используется простой текстовый препроцессор, производящий подстановку кусков текста. Содержимое исходных файлов для него делится на две категории:
- Директивы препроцессора - строки с
#
и до неэкроноированного символа переноса строки. Встречая эти директивы, препроцессор их обрабатывает, модифицируя свое поведение и заменяет. В случае с#include
директива будет заменена на содержимое соотв. файла. В случае с#define
(и большинством прочих директив) директива заменяется на на пустую строку. - Тест программы - все, что не является директивами препроцессора. При обработке текста программы при встрече известного препроцессору токена он заменят этот токен на токены для подстановки. Затем заново обрабатывает текст программы начиная с токлько что подставленных токенов. И повторяет этот процесс, пока в тексте программы больше не останется токенов для замены.
Таким образом, встретив в коде из вопроса:
- Препроцессор заменяет директиву
#include "lib.h"
содержимым файла. - Обрабатывая только что вставленный из заголовочного файла текст, натыкается на директиву
#define TEST __FILE__
- Запоминает, что при встрече в тексте программы токена
TEST
его надо будет заменить на токен__FILE__
, и заменяет директиву на пустую строку. - Натыкается на токен
TEST
в текстеmain.cpp
. - Заменяет
TEST
на__FILE__
по запомненному ранее правилу. - Обрабатывая только то вставленный текст, натыкается на токен
__FILE__
. - Заменяет
__FILE__
на строковый литерал с именем файла, в котором сейчас происходит подстановка, то бишь на "main.cpp".