__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.