Ответ 1
Раздел 6.6/3
, "Константные выражения", стандарта ISO C99 - это раздел, который вам нужен. В нем указано:
Константные выражения не должны содержать назначение, приращение, декремент, вызов функции, или запятыми, за исключением случаев, когда они содержатся в подвыражении, которое не является оценены.
В документе обоснования C99 от ISO есть этот небольшой фрагмент:
Целочисленное константное выражение должно включать только числа, которые можно узнать во время трансляции, и операторы без побочных эффектов.
И, поскольку нет смысла использовать оператор запятой вообще, если вы не полагаетесь на побочные эффекты, это бесполезно в постоянном выражении.
Таким образом, я имею в виду отсутствие разницы между двумя сегментами кода:
while (10, 1) { ... }
while (1) { ... }
так как 10
фактически ничего не делает. Фактически,
10;
- это абсолютно корректный, хотя и не очень полезный, оператор C, то, что большинство людей не понимает, пока они не узнают язык лучше.
Однако существует разница между этими двумя утверждениями:
while ( 10, 1) { ... }
while (x=10, 1) { ... }
В последнем случае используется оператор запятой, который должен установить переменную x
в 10
.
Что касается того, почему они не любят побочные эффекты в постоянных выражениях, то все точки постоянных выражений заключаются в том, что их можно оценивать во время компиляции, не требуя среды выполнения. ISO делает различие между трансляцией (временем компиляции) и среды выполнения (run-time).
Ключ к тому, почему ISO решил не требовать от компиляторов предоставления информации об окружающей среде (кроме файлов, содержащихся в заголовочных файлах, таких как limits.h
), можно найти несколько позже в документе обоснования:
Однако, хотя реализациям, безусловно, разрешено производить точно такой же результат в средах перевода и исполнения, что требует, чтобы это было невыносимым бременем для многих кросс-компиляторов.
Другими словами, ISO не хотела, чтобы производители кросс-компиляторов были обременены переносом среды выполнения для всех возможных целей.