g++-2.95 rejects cast to void
Bruno Haible
haible@ilog.fr
Thu Jun 17 03:21:00 GMT 1999
> 3.2/2 says `an expresion is potentially evaluated unless ...'
> The unless part does not mention casting to void.
In 3.2/2 the term "potentially evaluated" is only defined as an auxiliary
term in order to define the term "used". (That's what I infer from the
nicely HTMLized copy at http://www.cygnus.com/misc/wp/nov97/ .) This term,
in turn, specifies when the linker is justified in emitting error messages
about undefined member functions / conversion operators etc.
Seems to me that 5.2.9 and 5.4 contain all the lawyer language you need:
5.2.9/4:
Any expression can be explicitly converted to type cv void. The
expression value is discarded. ... The
lvalue-to-rvalue (_conv.lval_), array-to-pointer (_conv.array_), and
function-to-pointer (_conv.func_) standard conversions are not applied
to the expression.
5.4/5:
The conversions performed by
--a static_cast (_expr.static.cast_),
...
can be performed using the cast notation of explicit type conversion.
> 5.2.9/4 says `any expression can be explicitly converted to cv void,
> The value is discarded'.
Which means, side effects are executed, only the value is discarded [in
contrast to sizeof, which does not evaluate its argument expression].
> In evaluating a reference, the first thing you do is look through
> the reference (5/6). You can't evaluate an expression of incomplete type.
But 5.2.9/4 contains explicit language to skip the lvalue-to-rvalue
conversion, therefore the fact that the type is incomplete does not matter.
> So shouldn't `(void)x' behave the same regardless of whether `x' is plain
> `foobar' or `foobar &'?
Yes it should behave the same way. That's also what `static_cast<void>(x)'
does. One more test:
===============================================
struct foobar;
extern foobar y;
void bar (foobar& x)
{
static_cast<void>(x); // ok
static_cast<void>(y); // ok
(void)x; // error message, should be no error
(void)y; // error message, should be no error
x; // error message, fine
y; // error message, fine
}
===============================================
> What about the following?
>
> struct foobar;
> extern foobar obj;
> extern foobar &ref; // no initialization needed here
> ...
> (void)obj; // not valid
> (void)ref; // valid or not?
Both are valid - it's the lvalue-to-rvalue conversion which is not valid
when the type is incomplete, and this lvalue-to-rvalue conversion is
explicitly turned off by 5.2.9/4.
Bruno
More information about the Gcc-bugs
mailing list