C11, 6.10.1 Inclusión condicional, Restricciones, 1 (énfasis añadido):
La expresión que controla la inclusión condicional será una expresión constante entera
C11, 6.6 Expresiones constantes, 6 (énfasis añadido):
Una expresión de constante entera 117) tendrá un tipo entero y solo tendrá operandos que sean constantes enteras, constantes de enumeración, constantes de caracteres, expresiones
sizeof
cuyos resultados sean constantes enteras, expresiones_Alignof
y constantes flotantes que sean los operandos inmediatos de las conversiones.
$ cat t333.c #if (int)1.0 #endif $ gcc t333.c -std=c11 -pedantic -c t333.c:1:10: error: missing binary operator before token "1.0" 1 | #if (int)1.0
Aquí (int)1.0
en la expresión constante entera. Tiene tipo entero y operando, que es una constante flotante que es el operando inmediato de conversión. Sin embargo, por gcc
el código no es válido.
¿Significa que la "expresión constante entera" utilizada en las directivas de preprocesamiento 6.10 es limitada [1]? ¿Está explícitamente especificado en la norma?
[1] Por ejemplo, "excepto las expresiones sizeof
cuyos resultados son constantes enteras, expresiones _Alignof
y constantes flotantes que son los operandos inmediatos de las conversiones"
Necesita mirar 6.10.1p1 en su totalidad:
La expresión que controla la inclusión condicional debe ser una expresión constante entera excepto que: los identificadores (incluidos aquellos léxicamente idénticos a las palabras clave) se interpretan como se describe a continuación ; 166) , y puede contener expresiones de operadores unarios de la forma
defined identifier
o
defined ( identifier )
que se evalúan como 1 si el identificador está actualmente definido como un nombre de macro (es decir, si está predefinido o si ha sido objeto de una directiva de preprocesamiento
#define
sin una directiva#undef
intermedia con el mismo identificador de sujeto), 0 si No lo es.
Donde la nota al pie 166 dice:
- Debido a que la expresión constante de control se evalúa durante la fase de traducción 4, todos los identificadores son o no nombres de macro; simplemente no hay palabras clave, constantes de enumeración, etc.
Por lo tanto, el preprocesador no trata la palabra clave int
como una palabra clave, sino como un identificador y, por lo tanto, como un nombre de macro. Esto da como resultado una sintaxis no válida que provoca un error.
Esto significa que las expresiones constantes enteras que involucran una conversión, _Alignof
sizeof
están permitidas en una directiva #if
.