Connecting Tech Pros Worldwide Forums | Help | Site Map

Is it implementation-defined whether this errors?

zaimoni@zaimoni.com
Guest
 
Posts: n/a
#1: Aug 27 '08
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?

Eric Sosman
Guest
 
Posts: n/a
#2: Aug 27 '08

re: Is it implementation-defined whether this errors?


zaimoni@zaimoni.com wrote:
Quote:
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.
Quote:
The obvious complementary test case
>
#if 0
#elif
#endif
>
must error, as the control expression of the #elif is actually
needed.
I see no difference between this example and the first one.

--
Eric.Sosman@sun.com
zaimoni@zaimoni.com
Guest
 
Posts: n/a
#3: Aug 27 '08

re: Is it implementation-defined whether this errors?


On Aug 27, 9:26 am, Eric Sosman <Eric.Sos...@sun.comwrote:
Quote:
zaim...@zaimoni.com wrote:
Quote:
This is a test case I constructed for a vaporware standalone C99
preprocessor:
>
Quote:
#if 1
#elif
#endif
>
Quote:
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.
Quote:
Quote:
The obvious complementary test case
>
Quote:
#if 0
#elif
#endif
>
Quote:
must error, as the control expression of the #elif is actually
needed.
>
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.
Eric Sosman
Guest
 
Posts: n/a
#4: Aug 27 '08

re: Is it implementation-defined whether this errors?


zaimoni@zaimoni.com wrote:
Quote:
On Aug 27, 9:26 am, Eric Sosman <Eric.Sos...@sun.comwrote:
Quote:
>zaim...@zaimoni.com wrote:
Quote:
>>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.
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. Thus, 6.10.1p5 does not apply.
Quote:
Quote:
Quote:
>>The obvious complementary test case
>>#if 0
>>#elif
>>#endif
>>must error, as the control expression of the #elif is actually
>>needed.
> 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.
I'm also susceptible to going off-course, but you've not yet
convinced me that the course and I have become non-proximal ...
As I understand the matter, the #elif directive *is* processed, no
matter what the value of the controlling expression in the preceding
#if or #elif, because the #elif is not part of the group that the
preceding directive includes or suppresses.

6.10.1p5 applies to situations like this, which I think is
valid C despite its unusual appearance:

#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. The other four directives are, I think,
fully processed regardless of the control expressions' values.

--
Eric.Sosman@sun.com
zaimoni@zaimoni.com
Guest
 
Posts: n/a
#5: Aug 27 '08

re: Is it implementation-defined whether this errors?


On Aug 27, 12:32 pm, Eric Sosman <Eric.Sos...@sun.comwrote:
Quote:
zaim...@zaimoni.com wrote:
Quote:
On Aug 27, 9:26 am, Eric Sosman <Eric.Sos...@sun.comwrote:
Quote:
zaim...@zaimoni.com wrote:
>This is a test case I constructed for a vaporware standalone C99
>preprocessor:
>#if 1
>#elif
>#endif
Quote:
Quote:
Quote:
>....
Quote:
Quote:
Quote:
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.
>
Quote:
Yes -- *if* the #elif directive is being preprocessed.
>
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.
Quote:
Thus, 6.10.1p5 does not apply.
6.10.1p5 entails the tie-breaker I needed, however.
Quote:
Quote:
Quote:
>The obvious complementary test case
>#if 0
>#elif
>#endif
>must error, as the control expression of the #elif is actually
>needed.
I see no difference between this example and the first one.
>
Quote:
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.
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.)
Quote:
....
Quote:
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.
Quote:
#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.
Closed Thread