Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the @ character allowed in C source?

Obviously, having the compiler come across the @ character will cause a syntax error (unless it's a comment or string literal). However, if the character is found e.g. inside of an #if 0 block, is the program technically valid?

I tried this:

#define NOTHING(x)

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

with -pedantic -Wall -Wextra, on both gcc and clang and it gave no warnings. I'm not sure if that's guaranteed to work, or if they just don't have a specific warning for it.

I didn't find anything in the standard saying one way or the other, which is worrying. I don't want to base a tool on this only to find out that a standard compliant compiler chokes on it.

like image 267
mtijanic Avatar asked May 13 '16 16:05

mtijanic


1 Answers

You can include almost any character in a C program as long as it is either eliminated or stringified by the preprocessor. @ is a valid preprocessor token so it will not be flagged as an error in the preprocessing phases of compilation.

The standard does not prevent a compiler from issuing warnings about anything, and it is possible that a compiler would produce a warning in this case. But I don't know of one which does, and I would consider it a quality-of-implementation issue.

Relevant standard sections:

  • Definition of preprocessing-token in §6.4: "each non-white-space character that cannot be one of the above". Note that @@@@ is therefore four preprocessing-tokens.

  • §6.4/2, emphasis added: "Each preprocessing token that is converted to a token shall have the lexical form of a keyword, an identifier, a constant, a string literal, or a punctuator." As long as the @ are not "converted to a token", no error has occurred. The conversion to a token happens in phase 7 of the compilation process (see §5.1.1.2/7). That is long after the expansion of macros, which includes stringification, in phase 4.

like image 91
rici Avatar answered Sep 28 '22 07:09

rici