#включить __FILE__: разное значение __FILE__ между компиляторами: что говорит стандарт?

#c #recursion #include #c-preprocessor

#c #рекурсия #включить #c-препроцессор

Вопрос:

Пример кода ( t1.c ):

 #if defined(M1)
    printf("%sn", __FILE__);
#undef  M1
#elif   defined(M2)
#define M1
#include __FILE__
#undef  M2
#else
#include <stdio.h>
int main    ( void )
{
    printf("%sn", __FILE__);
#define M1
#include __FILE__
#define M2
#include __FILE__
    return 0;
}
#endif
 

Результаты:

 $ gcc t1.c amp;amp; ./a.exe
t1.c
t1.c
t1.c

$ clang t1.c amp;amp; ./a.exe
t1.c
./t1.c
./././t1.c

cl t1.c amp;amp; tc1
t1.c
d:TEMPt1.c
d:TEMPt1.c
 

Версии компилятора:

 cl: 19.25.28611
gcc: 10.2.0
clang: 11.0.0
 

Вопрос: Что говорит стандарт?

Комментарии:

1. В стандарте указано «Предполагаемое имя текущего исходного файла (символьный строковый литерал) «. Дает достаточно свободы для интерпретации.

Ответ №1:

C 2018 6.10.8.1 1 говорит:

Следующие имена макросов должны быть определены реализацией:

__FILE__ Предполагаемое имя текущего исходного файла (символьный строковый литерал).

Поскольку стандарт C не устанавливает никаких других требований __FILE__ , любой строковый литерал, который служит именем исходного файла, удовлетворяет этому требованию. Он может содержать или пропускать любые последовательности, например ./ , если строка является именем текущего исходного файла.

(Также есть примечание, в котором говорится, что предполагаемое имя исходного файла может быть изменено #line директивой.)

Комментарии:

1. Можно ли сделать вывод, что #include __FILE__ никогда не выходит из строя?