2016-05-13 27 views
7

Ovviamente, avere il compilatore che incontra il carattere @ causerà un errore di sintassi (a meno che non si tratti di un commento o di una stringa letterale). Tuttavia, se il personaggio viene trovato ad es. all'interno di un blocco #if 0, il programma è tecnicamente valido?Il carattere @ è consentito nell'origine C?

ho provato questo:

#define NOTHING(x) 

int main() 
{ 
    NOTHING(@@@@); 
    return 0; 
} 

con -pedantic -Wall -Wextra, sia gcc e clang e ha dato nessun avviso. Non sono sicuro che sia garantito che funzioni, o se semplicemente non hanno un avvertimento specifico per questo.

Non ho trovato nulla nello standard che dice in un modo o nell'altro, il che è preoccupante. Non voglio basare uno strumento su questo solo per scoprire che un compilatore conforme allo standard si soffoca su di esso.

risposta

9

È possibile includere quasi tutti i caratteri in un programma in C purché siano eliminati o impreziositi dal preprocessore. @ è un token preprocessore valido in modo che non venga contrassegnato come errore nelle fasi di pre-elaborazione della compilazione.

Lo standard non impedisce a un compilatore di emettere avvisi su qualsiasi cosa ed è possibile che un compilatore generi un avviso in questo caso. Ma non ne conosco uno che lo faccia e lo considererei un problema di qualità di attuazione.

rilevanti sezioni standard:

  • Definizione pre-elaborazione-token in § 6.4: "ogni carattere non-bianco-spazio che non può essere uno dei precedenti". Si noti che @@@@ è quindi quattro token di pre-elaborazione.

  • § 6,4/2, enfasi aggiunta: "Ogni pre-elaborazione di token che viene convertito in un gettone deve avere la forma lessicale di una parola chiave, un identificatore, una costante, una stringa letterale, o un punctuator." Finché lo @ non viene "convertito in token", non si è verificato alcun errore. La conversione in un token avviene nella fase 7 del processo di compilazione (vedere § 5.1.1.2/7). Questo è molto tempo dopo l'espansione delle macro, che comprende in stringa, in fase di 4.

+4

"@ è un preprocessore di token valida" - questa è la chiave qui, e la sezione relativa norma sembra essere [sezione C11 6.4] (http://port70.net/~nsz/c/c11/n1570.html#6.4), dove la definizione di 'preprocessing-token' include qualsiasi carattere non di spazi bianchi che non corrisponde alle altre categorie di token di preelaborazione. – user2357112

+0

Grazie! Questo risponde completamente alla mia domanda. – mtijanic

Problemi correlati