Why Is (Void) 0 a No Operation in C and C++

Why is (void) 0 a no operation in C and C++?

(void)0 (+;) is a valid, but 'does-nothing' C++ expression, that's everything. It doesn't translate to the no-op instruction of the target architecture, it's just an empty statement as placeholder whenever the language expects a complete statement (for example as target for a jump label, or in the body of an if clause).

From Chris Lutz's comment:

It should be noted that, when used as a macro (say, #define noop ((void)0)), the (void) prevents it from being accidentally used as a value (like in int x = noop;).

For the above expression the compiler will rightly flag it as an invalid operation. GCC spits error: void value not ignored as it ought to be and VC++ barks 'void' illegal with all types.

What is the purpose of (void)variable in C?

In general when one does not use an function argument, the compiler is likely to warn you about it. After all if you aren't going to use it why put it there in the first place?

In effect it is an artificial use of the argument that does nothing useful other than telling the compiler you know what you are doing, so "Shatupalready with the warning!"

(void) args works on all of the platforms that I have seen. I believe the __attribute((unused)) is a gcc specific thing.

Why use (void)1 as a no-op in C++?

There's no difference between (void)1 and (void)0.

What is the purpose of the statement (void)c;?

Maybe to avoid a compilation warning because c isn't used?

Why does (void)0 stop statement has no effect warnings?

The cast to void makes it clear that the programmer intends to throw the result away. The purpose of the warning is to indicate at that it's not obvious that the statement has no effect and thus it's useful to alert the programmer to that in case it was unintentional. A warning here would serve no purpose.

What is (void) with () in C

(void) has the form of a cast operation, but casting to void (note: not to void *) is normally not a useful thing to do.

In this context, though, (void) myFunc(); means that myFunc returns a value, and whoever wrote this line of code wanted to throw that value away and did not want the compiler to complain about this, and/or wanted to make it clear to future readers of the code that they were throwing the value away on purpose. In the generated code, (void) myFunc(); has exactly the same effect as myFunc(); with nothing in front.

Due to historic abuses of this notation, some compilers will warn you about not using the value of certain functions (e.g. malloc, read, write) even if you put (void) in front of them, so it's less useful than it used to be.

What's a portable way to implement no-op statement in C++?

I suspect that it might trigger warnings on some compilers

Unlikely, since ((void)0) is what the standard assert macro expands to when NDEBUG is defined. So any compiler that issues warnings for it will issue warnings whenever code that contains asserts is compiled for release. I expect that would be considered a bug by the users.

I suppose a compiler could avoid that problem by warning for your proposal (void)0 while treating only ((void)0) specially. So you might be better off using ((void)0), but I doubt it.

In general, casting something to void, with or without the extra enclosing parens, idiomatically means "ignore this". For example in C code that casts function parameters to void in order to suppress warnings for unused variables. So on that score too, a compiler that warned would be rather unpopular, since suppressing one warning would just give you another one.

Note that in C++, standard headers are permitted to include each other. Therefore, if you are using any standard header, assert might have been defined by that. So your code is non-portable on that account. If you're talking "universally portable", you normally should treat any macro defined in any standard header as a reserved identifier. You could undefine it, but using a different name for your own assertions would be more sensible. I know it's only an example, but I don't see why you'd ever want to define assert in a "universally portable" way, since all C++ implementations already have it, and it doesn't do what you're defining it to do here.

C++ What is the purpose of casting to void?

Multiple purposes depending on what you cast

  • Marking your intention to the compiler that an expression that is entirely a no-op is intended as written (for inhibiting warnings, for example)
  • Marking your intention to to the compiler and programmer that the result of something is ignored (the result of a function call, for example)
  • In a function template, if a return type is given by a template parameter type T, and you return the result of some function call that could be different from T in some situation. An explicit cast to T could, in the void case, prevent a compile time error:

    int f() { return 0; } void g() { return (void)f(); }
  • Inhibiting the compiler to choose a comma operator overload ((void)a, b will never invoke an overloaded comma operator function).

Note that the Standard guarantees that there will never be an operator void() called if you cast a class object to void (some GCC versions ignore that rule, though).



Related Topics



Leave a reply



Submit