question about void typecast

B

brad2000

I was doing a little bit of reading in the ISO C spec. about
typecasting to a void type. This caused me to have a question. In
particular, I'm curious to know about section 6.3.2.2 where the specs
says "is evaluated as a void expression, its value or designator is
discarded."

If I do the following:

#include <stdio.h>

int
main(int argc, char **argv)
{
int s = 12;

printf("non-void type = 0x%x\n", s);

(void)s;

return(0);
}

What is the effect of typecasting s to a void type. Does the compiler
just treat the line as a null statement?

Thanks.

-brad walker
 
H

Harald van Dijk

I was doing a little bit of reading in the ISO C spec. about typecasting
to a void type. This caused me to have a question. In particular, I'm
curious to know about section 6.3.2.2 where the specs says "is
evaluated as a void expression, its value or designator is discarded."

If I do the following:

(void)s;

What is the effect of typecasting s to a void type. Does the compiler
just treat the line as a null statement?

Yes, that's it. The expression s is evaluated, and then its value is
converted to void, so discarded. As a statement, you might as well have
written

s;

since this discards the value as well. Casts to void are useful pretty
much only for suppressing warnings. There is nothing wrong with

printf("Hello, world!\n");

but some tools will generate a warning that the return value of printf is
discarded, and require you to write

(void) printf("Hello, world!\n");

to indicate that you want to discard it. Similarly, some tools will
generate a warning for unused function parameters, and one use in a
conversion to void is enough to silence them. Whether that's a good idea
is mostly a style issue, and something you'll have to decide for
yourself. I don't believe there's any case in standard C where a
conversion to void is actually required.
 
M

Mark McIntyre

I was doing a little bit of reading in the ISO C spec. about
typecasting to a void type.

Just FYI, 'typecasting' is what happens to actors who play the same role
too long.
C has 'casting'. a cast is an explicit conversion from one type to another.
> int s = 12;
> (void)s;
What is the effect of typecasting s to a void type.

It causes s to be evaluated as a void type. Since the result isn't
assigned to anything, it is thrown away.
Does the compiler just treat the line as a null statement?

It was /already/ a null statement since it had no side-effects and
didn't assign anything! Any good compiler would entirely optimise it out.
 
J

Jack Klein

Just FYI, 'typecasting' is what happens to actors who play the same role
too long.
C has 'casting'. a cast is an explicit conversion from one type to another.

Thanks for that, so I don't have to point it out.
It causes s to be evaluated as a void type. Since the result isn't
assigned to anything, it is thrown away.

I know you know what you mean here, but I think your wording came out
poorly in the first sentence of the paragraph above.

I would not say 's' is evaluated as a void type, since void is an
incomplete type and incomplete types cannot be evaluated.

In the abstract machine, 's' is evaluated by performing lvalue to
rvalue conversion, yielding the int value 12.

The (void) does not perform an actual case, since you cannot convert a
value, or anything else, to an incomplete type.

Instead, I think the best way to define the meaning of an apparent
cast to void is actually to state that it is an explicit statement (to
the compiler, to code analysis tools, people reading the code) that
the value of the expression is explicitly discarded.

There is really no such thing as a "cast to void", anymore than there
is "passing a void to a function".
It was /already/ a null statement since it had no side-effects and
didn't assign anything! Any good compiler would entirely optimise it out.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
K

Keith Thompson

I was doing a little bit of reading in the ISO C spec. about
typecasting to a void type. This caused me to have a question. In
particular, I'm curious to know about section 6.3.2.2 where the specs
says "is evaluated as a void expression, its value or designator is
discarded."

If I do the following:

#include <stdio.h>

int
main(int argc, char **argv)
{
int s = 12;

printf("non-void type = 0x%x\n", s);

(void)s;

return(0);
}

What is the effect of typecasting s to a void type. Does the compiler
just treat the line as a null statement?

We usually refer to this as "casting" rather than "typecasting".

A cast is an operator, consisting of a type name in parentheses, that
specifies a type conversion. Type conversions can be either explicit
(specified by a cast operator) or implicit; there's no such thing as
an implicit cast. (I know you didn't mention "implicit casts", but
it's such a common error that I thought I'd take the opportunity to
clear it up in advance.)

In this particular context, the cast does nothing. This:
(void)s;
and this:
s;
do exactly the same thing: evaluate ``s'' and discard the result. In
the first statement, the result is discarded by the cast; in the
second, the result is discarded because it's an expression statement
(any expression with a semicolon appended to it can be an expression
statement).

Since the only thing evaluating ``s'' does is obtain its value, and
since that value is discarded anyway, the compiler can and almost
certainly will generate no code for the statement. (This wouldn't be
the case if s were declared volatile; don't worry about that.)

A couple of other comments about your code:

For printf, "%x" expects an unsigned int; you're giving it a signed
int. It happens that you can get away with it in this case, but it's
best to use the right format for the type:
printf("non-void type = %d\n", s);

The parentheses on the return statement are allowed, but they aren't
necessary:
return 0;

If you don't need command-line arguments, you can declare main as:
int main(void)
but it *must* return an int, whether you expect to use the result or
not. (That's not 100% true, but it's close enough.)
 
K

Keith Thompson

Jack Klein said:
(e-mail address removed) wrote:
[...]
Thanks for that, so I don't have to point it out.
It causes s to be evaluated as a void type. Since the result isn't
assigned to anything, it is thrown away.

I know you know what you mean here, but I think your wording came out
poorly in the first sentence of the paragraph above.

I would not say 's' is evaluated as a void type, since void is an
incomplete type and incomplete types cannot be evaluated.

Right, ``s'' is evaluted as an expression of type int; the result is
then converted to void.
In the abstract machine, 's' is evaluated by performing lvalue to
rvalue conversion, yielding the int value 12.

The (void) does not perform an actual case, since you cannot convert a
value, or anything else, to an incomplete type.

Instead, I think the best way to define the meaning of an apparent
cast to void is actually to state that it is an explicit statement (to
the compiler, to code analysis tools, people reading the code) that
the value of the expression is explicitly discarded.

There is really no such thing as a "cast to void", anymore than there
is "passing a void to a function".

That would be a valid and consistent way to describe it, but I'm
afraid the standard disagrees with your wording.

See C99's description of cast operators (6.5.4) and void conversions
(6.3.2.2).

Conversion to void discards the value.

In the abstract machine, ``s'' is evaluated before the value is
discarded. An extremely naive compiler might actually load the value
of ``s'' into, say, a register. But yes, eliminating such an
evaluation is a common, if not universal, optimization.
 
J

Jack Klein

Jack Klein said:
(e-mail address removed) wrote:
[...]
Thanks for that, so I don't have to point it out.
int s = 12;
(void)s;
What is the effect of typecasting s to a void type.

It causes s to be evaluated as a void type. Since the result isn't
assigned to anything, it is thrown away.

I know you know what you mean here, but I think your wording came out
poorly in the first sentence of the paragraph above.

I would not say 's' is evaluated as a void type, since void is an
incomplete type and incomplete types cannot be evaluated.

Right, ``s'' is evaluted as an expression of type int; the result is
then converted to void.

Actually, the standard does not say that. In fact it disallows it:

6.2.5 p19 "The void type comprises an empty set of values; it is an
incomplete type that cannot be completed."

6.3 p1 "Several operators convert operand values from one type to
another automatically. This subclause specifies the result required
from such an implicit conversion, as well as those that result from a
cast operation (an explicit conversion)."

A conversion is something that converts values from one type to
another type. It is impossible to convert any value to the void type,
since it is defined as not having any values at all.
That would be a valid and consistent way to describe it, but I'm
afraid the standard disagrees with your wording.

See C99's description of cast operators (6.5.4) and void conversions
(6.3.2.2).

Conversion to void discards the value.

There is no such thing as conversion to void. It is not possible to
convert a value of any type to a void value. In fact, even though
6.3.2.2 is in the conversions section, it reiterates the fact that a
void expression (not void type) has a nonexistent value.

A (void) cast operator creates a void expression, it does not cause a
value to be converted to void.

It is not possible to convert a value to void.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
K

Keith Thompson

Jack Klein said:
Jack Klein said:
[...]
Thanks for that, so I don't have to point it out.

int s = 12;
(void)s;
What is the effect of typecasting s to a void type.

It causes s to be evaluated as a void type. Since the result isn't
assigned to anything, it is thrown away.

I know you know what you mean here, but I think your wording came out
poorly in the first sentence of the paragraph above.

I would not say 's' is evaluated as a void type, since void is an
incomplete type and incomplete types cannot be evaluated.

Right, ``s'' is evaluted as an expression of type int; the result is
then converted to void.

Actually, the standard does not say that. In fact it disallows it:

6.2.5 p19 "The void type comprises an empty set of values; it is an
incomplete type that cannot be completed."

6.3 p1 "Several operators convert operand values from one type to
another automatically. This subclause specifies the result required
from such an implicit conversion, as well as those that result from a
cast operation (an explicit conversion)."

A conversion is something that converts values from one type to
another type. It is impossible to convert any value to the void type,
since it is defined as not having any values at all.
[snip]
See C99's description of cast operators (6.5.4) and void conversions
(6.3.2.2).

Conversion to void discards the value.

There is no such thing as conversion to void. It is not possible to
convert a value of any type to a void value. In fact, even though
6.3.2.2 is in the conversions section, it reiterates the fact that a
void expression (not void type) has a nonexistent value.

A (void) cast operator creates a void expression, it does not cause a
value to be converted to void.

It is not possible to convert a value to void.

Hmm. I don't have my copy of the standard handy at the moment. When
I read the section that describes the cast operator, I didn't see any
exception for ``(void)'' casts; as I recall, it said that a cast
converts the expression to the target type. I'll take a closer look
at both sections later and post again. Possibly the standard is
internally inconsistent.
 
S

Stephen Montgomery-Smith

I was doing a little bit of reading in the ISO C spec. about
typecasting to a void type. This caused me to have a question. In
particular, I'm curious to know about section 6.3.2.2 where the specs
says "is evaluated as a void expression, its value or designator is
discarded."

If I do the following:

#include <stdio.h>

int
main(int argc, char **argv)
{
int s = 12;

printf("non-void type = 0x%x\n", s);

(void)s;

return(0);
}

What is the effect of typecasting s to a void type. Does the compiler
just treat the line as a null statement?

Thanks.

-brad walker

This is *literally* a discussion about nothing!
 

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,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top