GCC 4.5.0 также не меняет X.
Ответ будет заключаться в том, как препроцессор интерпретирует токены препроцессора, и в правиле «максимального мунка». Правило «максимального мунка» - это то, что диктует, что «x +++++ y» трактуется как «x ++ ++ + y» и, следовательно, является ошибочным, а не «x ++ + ++ y», что законны.
Проблема в том, почему препроцессор интерпретирует '1e-X' как один токен предварительной обработки. Ясно, что он будет обрабатывать '1e-10' как один токен. Не существует действительного толкования для '1e-', если за ним не следует цифра после прохождения препроцессора. Итак, я должен предположить, что препроцессор видит '1e-X' как один токен (фактически ошибочный). Но я не анализировал правильные положения в стандарте, чтобы увидеть, где это требуется . Но определение «числа предварительной обработки» или «числа pp» в стандарте (см. Ниже) несколько отличается от определения допустимой целочисленной константы или константы с плавающей запятой и допускает множество «чисел pp», которые недопустимы как целое число или константа с плавающей точкой.
Если это поможет, выход компилятора Sun C для 'cc -E -v soq.c' будет:
# 1 "soq.c"
# 2
int main()
{
"soq.c", line 4: invalid input token: 1e-X
double a = 1e-X ;
return 0;
}
#ident "acomp: Sun C 5.9 SunOS_sparc Patch 124867-09 2008/11/25"
cc: acomp failed for soq.c
Таким образом, по крайней мере один компилятор C отклоняет код в препроцессоре - возможно, препроцессор GCC немного провисает (я пытался спровоцировать его на жалобу gcc -Wall -pedantic -std=c89 -Wextra -E soq.c
, но он не издал писк) И использование 3 X в макросе и в нотации «1e-XXX» показало, что все три X были использованы и GCC, и компилятором Sun C.
C Стандартное определение числа предварительной обработки
Из стандарта C - ISO / IEC 9899: 1999 §6.4.8 Номера для предварительной обработки:
pp-number:
digit
. digit
pp-number digit
pp-number identifier-nondigit
pp-number e sign
pp-number E sign
pp-number p sign
pp-number P sign
pp-number .
Учитывая это, «1e-X» является действительным «pp-номером», и, следовательно, X не является отдельным токеном (и не является «XXX» в «1e-XXX» отдельным токеном). Следовательно, препроцессор не может расширять X; это не отдельный токен, подлежащий расширению.