What does casting to `void` really do?
Possible use:
auto it = list_.before_begin();
for (auto& entry : list_)
{
(void)entry; //suppress warning
++it;
}
Now the iterator 'it' points to the last element
This statement:
(void)x;
Says "Ignore the value of x." There is no such type as void
- it is the absence of a type. So it's very different from this:
(int)x;
Which says "Treat x as if it were an integer." When the resulting integer is ignored, you get a warning (if it's enabled).
When you ignore something which is nothing, it is not considered a problem by GCC--and with good reason, since casting to void is an idiomatic way to ignore a variable explicitly in C and C++.
The standard does not mandate generating a warning ("diagnostic" in standardese) for unused local variables or function parameters. Likewise, it does not mandate how such a warning might be suppressed. Casting a variable expression to void
to suppress this warning has become an idiom in the C and later C++ community instead because the result cannot be used in any way (other than e.g. (int)x
), so it's unlikely that the corresponding code is just missing. E.g.:
(int)x; // maybe you meant f((int)x);
(void)x; // cannot have intended f((void)x);
(void)x; // but remote possibility: f((void*)x);
Personally, I find this convention too obscure still, which is why I prefer to use a function template:
template<typename T>
inline void ignore(const T&) {} // e.g. ignore(x);
The idiomatic way to ignore function parameters is, however, to omit their name (as seen above). A frequent use I have for this function is when I need to be able to name a function parameter in conditionally compiled code such as an assert
. I find e.g. the following more legible than the use of #ifdef NDEBUG
:
void rate(bool fantastic)
{
assert(fantastic);
ignore(fantastic);
}
Casting to void is used to suppress compiler warnings. The Standard says in §5.2.9/4 says,
Any expression can be explicitly converted to type “cv void.” The expression value is discarded.