De acordo com CPPReference , #if
é seguido por uma expressão constante. sizeof
é um operador válido em expressões constantes. Mas quando escrevo isso e compilo com clang ou gcc, ele falha:
#if sizeof(char) == 1
#endif
saída do clang:
sizeof in preprocessor directive.c:1:5: error: function-like macro 'sizeof' is not defined
#if sizeof(char) == 1
^
1 error generated.
Saída do gcc:
sizeof in preprocessor directive.c:1:11: error: missing binary operator before token "("
1 | #if sizeof(char) == 1
| ^
O CPPReference está errado ou os compiladores estão errados?
Ambos estão corretos e parece que você entendeu mal o que diz o cppreference.
Do projeto padrão (N3096) 6.10.1, Inclusão condicional:
(ênfase minha)
Isso significa que da perspectiva do pré-processador, no contexto de
#if
,sizeof(char)==1
é simplesmente substituído para produzir0(0)==1
, já que essa não é uma expressão constante válida, o programa está mal formado e o compilador deve emitir um diagnóstico, o que os compiladores realmente fazem e são portanto, em conformidade.sizeof
não é nada especial aqui, nem échar
. Eles são como quaisquer outros identificadores que não foram#defined
e são substituídos por 0. Você pode testar sozinho com coisas como#if sizeof *1
e#if char+1
muito mais.A cotação cppreference não está errada. No seu link, a frase completa é
Isso basicamente afirma a mesma coisa que no padrão e certamente não significa "qualquer expressão constante pode ser usada aqui" como você parece acreditar.
Acho que o que foi dito acima já deve ser suficiente para responder à sua pergunta. Só para deixar mais claro que os códigos não podem funcionar como você espera, como apontam os comentários, o tratamento acontece
sizeof
na fase 7 da tradução, muito depois da última fase de pré-processamento, fase 4. Informalmente, eu apenas digamos que issosizeof
seja tratado pelo compilador e o pré-processador não saiba nada sobre isso. Seja como for, é impossível avaliarsizeof(char)==1
como verdadeiro em uma#if
condição.Falta ao CPPReference a precisão de que palavras-chave que possuem a forma de identificadores são tratadas como identificadores e não como palavras-chave para fins de avaliação da expressão constante. Essa precisão já estava presente no C89.