Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

void identifiers are primary expressions?

32 views
Skip to first unread message

Jun Woong

unread,
May 22, 2012, 5:14:46 AM5/22/12
to
Given this code:

extern void p1;
extern const void p2;

p1;
p2;
(void)p1;
(void)p2;

is a conforming implementation required to issue diagnositcs?
I'm not asking if a s.c. program can contain references to p1 or p2
in expressions; I know that it cannot because there is no way to
provide their definitions. What I'm asking is whether using an
identifier declared as having void or qualified void type in an
expression results in syntax error or simply in UB.

Relevant citations from C99:

6.5.1p2 says:
An identifier is a primary expression, provided it has been
declared as designating an object (in which case it is an lvalue)
or a function (in which case it is a function designator).

If p1 and p2 above cannot be primary expressions, their use in
expressions triggers syntax error while parsing expressions.

6.3.2.1p1 says:
An lvalue is an expression with an object type or an incomplete
type other than /void/.

Note here that /void/ written in italics excludes qualified types;
see DR012 for C90.

Thanks in advance.


--
Jun, Woong (woong.jun at gmail.com)

Jun Woong

unread,
May 24, 2012, 4:52:06 AM5/24/12
to
Jun Woong <wo...@icu.ac.kr> wrote:
> Given this code:
>
>     extern void p1;
>     extern const void p2;
>
>     p1;
>     p2;
>     (void)p1;
>     (void)p2;
>
> is a conforming implementation required to issue diagnositcs?
> I'm not asking if a s.c. program can contain references to p1 or p2
> in expressions; I know that it cannot because there is no way to
> provide their definitions. What I'm asking is whether using an
> identifier declared as having void or qualified void type in an
> expression results in syntax error or simply in UB.
>
> Relevant citations from C99:
>
> 6.5.1p2 says:
>   An identifier is a primary expression, provided it has been
>   declared as designating an object (in which case it is an lvalue)
>   or a function (in which case it is a function designator).
>
> If p1 and p2 above cannot be primary expressions, their use in
> expressions triggers syntax error while parsing expressions.

I found my note on this part that says using an identifier declared
as having void type in an expression results in implicit UB, because
the standard is silent on what happens if an identifier describes an
object but has void type, which agrees with most implementations. I
don't remember when and where I got this interpretation, however.

Harald van Dijk

unread,
May 24, 2012, 2:36:09 PM5/24/12
to
On May 22, 11:14 am, Jun Woong <wo...@icu.ac.kr> wrote:
> Given this code:
>
>     extern void p1;
>     extern const void p2;
>
>     p1;
>     p2;
>     (void)p1;
>     (void)p2;
>
> is a conforming implementation required to issue diagnositcs?
[...]
> Note here that /void/ written in italics excludes qualified types;
> see DR012 for C90.

The answer for DR012 says

extern const void p2;
&p2;

is valid. In &p2;, p2 is a primary expression, so DR012 answers your
question for the lines involving p2.

A reasonable argument can be made that both p1 and p2 are declared as
designating objects, despite not having object type, and that the
parenthesised text in 6.5.1p2 ("in which case it is an lvalue") is
incorrect. This matches C11, in which both void and const void are
object types.

Jun Woong

unread,
May 24, 2012, 8:59:33 PM5/24/12
to
Harald van Dijk <true...@gmail.com> wrote:
> On May 22, 11:14 am, Jun Woong <wo...@icu.ac.kr> wrote:
>
> > Given this code:
>
> >     extern void p1;
> >     extern const void p2;
>
> >     p1;
> >     p2;
> >     (void)p1;
> >     (void)p2;
>
> > is a conforming implementation required to issue diagnositcs?
> [...]
> > Note here that /void/ written in italics excludes qualified types;
> > see DR012 for C90.
>
> The answer for DR012 says
>
>   extern const void p2;
>   &p2;
>
> is valid. In &p2;, p2 is a primary expression, so DR012 answers your
> question for the lines involving p2.

Not quite. Qualified void is excluded from /void/ in the text of the
standard, so there is no problem in p2's being a primary expression.
Of course, being a primary expression does not make unadorned use of
p2 in expressions valid since we have:

6.3.2.1p2
Except when it is the operand of [sizeof, &, ++, -- ...], an lvalue
that does not have array type is converted to the value stored in
the designated object [...] If the lvalue has incomplete type and
does not have array type, the behavior is undefined.

What about p1? It designates an object (with unenough information
that cannot be satisfied forever), but because it is of unqualified
void type, it is uncertain for that identifier to be a primary
expression.

>
> A reasonable argument can be made that both p1 and p2 are declared as
> designating objects, despite not having object type, and that the
> parenthesised text in 6.5.1p2 ("in which case it is an lvalue") is
> incorrect.

Agreed.
0 new messages