Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the C11 keyword '_Atomic' count as type qualifier or specifier if followed by a whitespace and a left parenthesis?

Reading the N1570 draft of the C11 standard, it says on p. 121 about the _Atomic keyword:

If the _Atomic keyword is immediately followed by a left parenthesis, it is interpreted as a type specifier (with a type name), not as a type qualifier.

Now I am wondering, what constitutes as 'immediate' in this context?

I find the wording quite ambiguous: Are the two following lines of code guaranteed by the standard to always be identical?

Unambiguous:

static _Atomic(type) var;

Ambiguous:

static _Atomic (type) var;

Does the insertion of a whitespace destroy the immediacy of the left parenthesis?

While in the first case, the keyword is always a type specifier, in the second case I am not sure whether it is a type specifier or a type qualifier and whether that is a question of interpretation or firmly defined by the standard. I am also referring to cases where 'var' is a pointer.

like image 882
programonkey Avatar asked Jul 15 '19 20:07

programonkey


2 Answers

_Atomic as a type specifier or type qualifier is shown in the grammar in clauses 6.7.2.4 and 6.7.3, respectively. The grammar is expressed in tokens (the terminal symbols of the grammar are the tokens defined by the C specification), and the grammar is analyzed in translation phase 7 (clause 5.1.1.2):

White-space characters separating tokens are no longer significant. Each preprocessing token is converted into a token. The resulting tokens are syntactically and semantically analyzed and translated as a translation unit.

Thus, white space is irrelevant.

like image 80
Eric Postpischil Avatar answered Oct 23 '22 11:10

Eric Postpischil


Your two lines of code are identical; "immediately followed by" means the next phase 7 token, not the next character in the source file.

I don't believe this is ever stated explicitly anywhere, but it's instructive to compare the specification of the one place in C where the presence or absence of whitespace between an identifier and a left parenthesis does control which of two grammar rules applies:

#define foo(bar) ...  // defines function-like macro 'foo(bar)' with replacement '...'
#define foo (bar) ... // defines object-like macro 'foo' with replacement '(bar) ...'

That's 6.10.3, easiest understood by reading paragraphs 9, 10, and 3 in that order:

[9] A preprocessing directive of the form

# define identifier replacement-list new-line

defines an object-like macro ...

[10] A preprocessing directive of the form[s]

# define identifier lparen identifier-listopt ) replacement-list new-line
[...two other forms...] 

defines a function-like macro ...

[3] There shall be white-space between the identifier and the replacement list in the definition of an object-like macro.

The inference you can draw from this is that when the C standard means to give whitespace significance in the grammar, it says so explicitly. When there is no such explicit statement, you can assume that the presence or absence of whitespace is only significant when it affects how the source text is divided into tokens.

like image 22
zwol Avatar answered Oct 23 '22 11:10

zwol