__FILE__ В .h что он разрешает
Существует ли спецификация того, как макрос __FILE__
будет расширен, если он находится в .h
?
Если я определяю в foo.h
#define MYFILE __FILE__
И включите его в foo.c
#include "foo.h"
int main(){
printf("%s",MYFILE);
....
}
Делает ли этот вывод foo.h
или foo.c
? (Да, я понимаю, что это глупый пример)
Извините за то, что должно быть простым вопросом. Документация в Интернете кажется противоречивой. За то, что стоит VS2008, возвращается как foo.c
, что я и ожидал.... Думаю. Я просто пытаюсь подтвердить, определено ли это поведение.
Ответы
Ответ 1
Совет, приведенный в yan , является "в целом правильным". То есть значение __FILE__
является именем текущего исходного файла при использовании макроса, а не при определении макроса. Однако это не совсем правильно - и вот контрпример:
$ cat x.h
static void helper(void)
{
printf("%s:%d helper\n", __FILE__, __LINE__);
}
$ cat x.c
#include <stdio.h>
#include "x.h"
int main(void)
{
helper();
printf("%s:%d\n", __FILE__, __LINE__);
return 0;
}
$ make x
cc -Wall -Wextra -std=c99 -g x.c -o x
$ ./x
x.h:3 helper
x.c:7
$
Это надуманный пример; в C вы очень редко помещаете фактический код в заголовок, как я здесь, - если вы не используете функции inline
. Но вывод показывает, что существуют ситуации, когда имя заголовка может быть правильным именем, которое __FILE__
расширяется до.
Ответ 2
Он всегда будет возвращать .c, где он использовался, поскольку __LINE__
и __FILE__
разрешаются после предварительного процессора. Таким образом, вы можете написать отладочные макросы, которые используют __FILE__
и __LINE__
, и указывать на них, где появляются инструкции отладки.
Ответ 3
Макро-расширение (всех макросов, а не только специальных, таких как __FILE__
) выполняется после подстановки #include
, поэтому да, на это поведение можно положиться.
Ответ 4
Фактический язык в стандарте (§6.10.8):
__FILE__
Предполагаемое имя текущего исходного файла (литерал символьной строки).
Поскольку макроразложение происходит после обработки #include
, "текущий исходный файл" является скомпилированным предварительно обработанным .c файлом.
Ответ 5
Этот макроС#define выполняет личную переделку замены текста. К моменту, когда компилятор C попадает в ваш файл foo.c, он видит:
printf("%s", __FILE__);
поэтому вы получаете foo.c.