42

Possible Duplicate:
casting unused return values to void

What is the purpose of (void) before a function call, for example

(void)func1();

I assume this is the same as simply calling func1();

Therefore is the (void) call simply to let other programmers know that the return type will be ignored, for instance if func1() had a return type of int, or does the compiler perhaps perform some optimizations on the function? Perhaps there is another reason behind it altogether - is it even legal C++ or perhaps is it a remnant of C seen in some legacy code.

Thanks

Community
  • 1
  • 1
const_ref
  • 4,016
  • 3
  • 23
  • 38
  • 4
    Possible duplicate of [casting unused return values to void](http://stackoverflow.com/q/689677/1202636), and a lot of other questions... anyway, I don't think programmers should put garbage in code just to make _their_ compiler happy because _they_ turn up useless and/or stupid warnings supported by _that_ compiler. And about _"to make explicity that we don't care about the result of the expression"_, well, isn't it obvius since we're not doing anything with it? – effeffe Dec 19 '12 at 14:32
  • 4
    @effeffe This isn't garbage, this is _not_ a programmer telling the compiler to shut up. This is a programmer telling the reader of the code: "I know that this function returns something, but I don't care". As opposed to `func1();` which means "Either I know that this function returns something and I don't care, or I have forgotten to handle the return type properly and made a fatal bug". For that same reason, a compiler warning about unhandled return types can never be useless/stupid. – Lundin Dec 19 '12 at 14:49
  • 4
    @Lundin so you usually write `(void) printf("hello");`? – effeffe Dec 19 '12 at 14:50
  • @effeffe That's a silly example, since it is such a well-known function. The (void) syntax is what you should use when dealing with user-defined functions, API/library functions etc. At any rate, you should probably not use stdio.h in production code, so you could decide to turn that warning on in the release build only. – Lundin Dec 19 '12 at 14:54
  • @Lundin hmm, I don't like to be inconsistent in my code style choices, but it's just a matter of taste here. I prefer to think that people read docs before use a function, but your choice makes sense, though I think most of people do/did this to shut up the compiler (in fact, almost every answer in this question and in its duplicates say so). – effeffe Dec 19 '12 at 15:06
  • @effeffe So you usually write [`scanf("%d", &x)`](http://www.gidnetwork.com/b-63.html)? Or perhaps you aren't using scanf in production code... – Lundin Dec 19 '12 at 15:08
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/21393/discussion-between-effeffe-and-lundin) – effeffe Dec 19 '12 at 15:10

4 Answers4

27

A cast to void can have semantic effect in one case: where a value is an operand of the comma operator and overrides the comma operator, a cast to void will suppress it:

struct S {
  int operator,(int) { return 0; }
};
std::cout << (S(), 42) << '\n';           // prints '0'
std::cout << ((void) S(), 42) << '\n';    // prints '42'
ecatmur
  • 152,476
  • 27
  • 293
  • 366
  • +1 (and I wish I would pony up more than that). of all the answers I've seen in this post, this is a good *functional* reason for doing this. It actually *means* something besides "nothing to see here" and "shut up, silly compiler" like the other answers seem to be honed on. Thanks for this. – WhozCraig Dec 19 '12 at 15:16
  • 1
    I don't knew about this purpose in C++. There is another purpose for C programmers; C programmers do it to avoid compiler-warnings such as "unused return value". – Jack Dec 19 '12 at 16:53
26

It prevents warning if some function are declared with attribute : "Warn if return value not used/checked"

Maybe a duplicate of Warning: ignoring return value of 'scanf', declared with attribute warn_unused_result

Check the documentation of gcc : http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html (warn_unused_result) for more details

Community
  • 1
  • 1
benjarobin
  • 4,410
  • 27
  • 21
  • Thanks! I did think there would be a more useful reason to use it. – const_ref Dec 19 '12 at 14:33
  • 2
    Note that if a function has been declared this way, then probably for good reason. So you should add a check for the return value instead of blatantly ignoring it. – datenwolf Dec 19 '12 at 14:33
  • 1
    @datenwolf: When was the last time you checked the return result of `printf`? :-) – Kerrek SB Dec 19 '12 at 14:45
  • 1
    @KerrekSB He's talking about functions declared with said attribute instead of generally functions declared with a return value at all, I think. And I hope no reasonable standard library declares `printf` with such a rubbish attribute. – Christian Rau Dec 19 '12 at 14:49
  • Even if the compiler doesn't complain about the difference between `printf(...)` and `(void) printf(...)`, other tools such as lint will. Note well: I'm not advocating the practice. – David Hammen Dec 19 '12 at 14:55
  • @KerrekSB When was the last time you checked the returned result of `scanf`? Also, if the return value of printf wasn't such useless information, people would actually check it. It is a very odd function. – Lundin Dec 19 '12 at 14:58
5

It means very little. It is explicitly turning the line to a void expression, that is an expression that is only used for its side effects and whose value is discarded. So the lines

func1();

and

(void)func1();

will do the same thing. There could be some optimization that can be performed if the compiler knows the value of the expression is not used, but it is likely that compiler can figure it out with or without the explicit (void).

It could be used as a form of documentation where the programmer is trying to make it obvious that they are not using the value of the expression.

Jainendra
  • 24,713
  • 30
  • 122
  • 169
3

Another strange use is to allow the function of unknown return type to be used adjacent to the , operator as a sequence operator. Ie, decltype( f(), g() ) technique, where you want to say "f can be operated on with (), as can g, and I want this type to be the type that g() returns". However, if f() returns a type such that operator, is overloaded, the result will be unexpected.

So you do decltype( void(f()), g() ), and discard the return value of f() before invoking operator,, so you are guaranteed to get the built-in sequence operator instead of some unknown override type.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524