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

2

8

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.

Tekla answered 15/7, 2019 at 20:1 Comment(1)
I don't have a reference to the standard to support this, but I imagine "immediate" means "the next token", rather than the next character.Inbreathe
P
10

_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.

Precautionary answered 15/7, 2019 at 20:10 Comment(2)
Reminder that the compiler uses the "as-if rule" here. The standard specifies that each parsing phase completes all at once, even if the actual implementation pulls them lazily.Suanne
@o11c: That has no relevance here.Precautionary
M
6

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.

Markup answered 15/7, 2019 at 20:28 Comment(1)
Thanks, this is an interesting example. To me, your answer is just as good as the one that Eric Postpischil gave, but unfortunately I can only pick one as the accepted answer.Tekla

© 2022 - 2024 — McMap. All rights reserved.