#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__
никогда не выходит из строя?