Is it implementation-defined whether this errors?

Z

zaimoni

This is a test case I constructed for a vaporware standalone C99
preprocessor:

#if 1
#elif
#endif

The text did not permit quickly deciding whether the syntax relaxation
for preprocessing directives in blocks that aren't processed (C99 6.10
paragraph 4) dominates knowing what an elif-block actually was (C99
6.10 paragraph 1). If 6.10 paragraph 4 dominates, this should warn
(as the preprocessor got lucky). If C99 6.10 paragraph 1 dominates,
this should error.

The obvious complementary test case

#if 0
#elif
#endif

must error, as the control expression of the #elif is actually
needed. So I tentatively decided to make the first test case behave
like the obvious one: error [why should it only warn just because we
got lucky?].

When I ran my test suite against GCC's cpp, the first test case only
warned. Since this is a legitimate implementation: did I miss
something that guarantees that the syntax relaxation dominates knowing
that the elif-block is well-formed?
 
Z

zaimoni

This is a test case I constructed for a vaporware standalone C99
preprocessor:
#if 1
#elif
#endif
The text did not permit quickly deciding whether the syntax relaxation
for preprocessing directives in blocks that aren't processed (C99 6.10
paragraph 4) dominates knowing what an elif-block actually was (C99
6.10 paragraph 1). If 6.10 paragraph 4 dominates, this should warn
(as the preprocessor got lucky). If C99 6.10 paragraph 1 dominates,
this should error.

The question boils down to whether #elif by itself is a malformed
#elif directive (because there's no expression) or whether it's just
a non-directive (because it doesn't parse as a directive). 6.10p3
settles the issue:

"[...] A non-directive shall not begin with any of the
directive names appearing in the syntax."

That is, no line beginning with #elif can be a non-directive, so it
must be treated as a directive, and since an #elif alone does not
match the syntax of any preprocessor directive it's an error.

Yes -- *if* the #elif directive is being preprocessed.
I see no difference between this example and the first one.

Superficially:
Whether the first case's malformed #elif directive is actually being
preprocessed (as a top-level construct) is a "this sentence is false"
paradox. (If I'm going off-course, this is why.) With the second
case, it's a "this sentence is true" non-paradox.

We have to preprocess the #elif directive to determine that there is
an elif-block to not preprocess. (I chose to error at that point,
then discard the malformed elif-block.) But as the starting line of
the not-preprocessed elif-block we're not supposed to preprocess it
after all -- which trips the "any tokens allowed" override for blocks
that aren't preprocessed.
 
Z

zaimoni

It is a directive, and it is not inside a skipped group, so
it is processed. The grammar of 6.10p1 makes it clear that the
#elif is not part of the if-group that is included or omitted by
the #if, but marks the start of the elif-group that follows the
if-group in the same if-section.
Agreed.

Thus, 6.10.1p5 does not apply.

6.10.1p5 entails the tie-breaker I needed, however.

What I had not noticed: 6.10.1p5 entails that an #elif directive does
not suppress itself. This dispels the claimed paradox. (I plausibly
overlooked a more direct statement to that effect.)
6.10.1p5 applies to situations like this, which I think is
valid C despite its unusual appearance:

I'm certain your following example is valid C.
#if 0
#if *-*-*-*-*-*-*-*
#elif |-|-|-|-|-|-|-|
#elif <<<<<-=-=->>>>>
#endif you must this old grey head
#elif 0
#else
#endif

IMHO, the directives in the inner if-section -- fully contained within
the if-group of the outer if-section -- are processed only as far as
their names, as 6.10.1p5 says.

Yes, this is unequivocal.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,906
Latest member
SkinfixSkintag

Latest Threads

Top