8

I see it when I read pugixml source code and I really don't know why it's there.

void foo(void* ptr) {
    (void)!ptr;  // What does this line do?
}

1 Answers1

9

(void)ptr; is a common way to suppress "unused parameter" warnings, which may be necessary when the function signature is required to contain more parameters than the function uses (e.g. in a callback, if the 'user data' parameter is not used).

The ! is new to me, though it is superfluous in this context because the return value is just thrown away.

nneonneo
  • 171,345
  • 36
  • 312
  • 383
  • The ``!`` probably forces an operation so it cannot simply discard the usage. – D.Shawley Apr 16 '13 at 01:49
  • 4
    To me it seems like unnecessary paranoia. The cast to void is there to make the parameter "seem" used, and every compiler I know of understands this and avoids emitting the unused parameter warning. – nneonneo Apr 16 '13 at 01:51
  • `!` also returns a `bool`. It might avoid a "can't cast pointer to non-integer" warning or something similar. Personally, I'm surprised you can typecast to `void` at all. – Mike DeSimone Apr 16 '13 at 02:04
  • Open Watcom C/C++ 1.9 doesn't get [this one](http://ideone.com/lQ5Wdm) right. It removes the pointer dereference and there's no crash. – Alexey Frunze Apr 16 '13 at 02:05
  • @MikeDeSimone The left operand of the comma operator is implicitly cast to `void` per the C standard. – Alexey Frunze Apr 16 '13 at 02:06
  • @AlexeyFrunze: you dereferenced an invalid pointer and invoked undefined behaviour. That code isn't required to crash, or in fact do anything sensible. The compiler is justified in optimizing away the dereference. – nneonneo Apr 16 '13 at 02:09
  • I'm fairly certain it wouldn't dereference any pointer in that case, not just NULL. – Alexey Frunze Apr 16 '13 at 02:14
  • @AlexeyFrunze: Any *valid* dereference would have no side-effects, and any *invalid* dereference would trigger UB. So the compiler can optimize it out. (Note that you never used *`volatile`*). – nneonneo Apr 16 '13 at 02:15
  • A valid dereference of a pointer to a volatile object is a side effect. – Alexey Frunze Apr 16 '13 at 02:17
  • ...you did use `volatile`. Clearly a reading comprehension fail on my part :). So yeah, compiler bug. Probably. – nneonneo Apr 16 '13 at 02:19
  • I just looked at the disassembly of the object file produced from compilation of that single `blah()` function (not of the whole program) and there's only `ret` in the function, so it's a bug. – Alexey Frunze Apr 16 '13 at 02:23