How to Implement No-Op MACro (Or Template) in C++

How do I implement no-op macro (or template) in C++?

As mentioned before - nothing.

Also, there is a misprint in your code.

it should be #else not #elif. if it is #elif it is to be followed by the new condition

#include <iostream>   

#ifdef NOOP
#define conditional_noop(x) do {} while(0)
#else
#define conditional_noop(x) std::cout << (x)
#endif

Have fun coding!
EDIT: added the [do] construct for robustness as suggested in another answer.

Proper C preprocessor macro no-op

See C #define macro for debug printing for an explanation of why you want a different form of no-op. You want to have the compiler parse the debug printing code even when you aren't using it so that errors do not creep in.

How does one execute a no-op in C/C++?

If it really is for a ternary operator that doesn't need a second action, the best option would be to replace it for an if:

if (a!=b) cout << "not equal";

it will smell a lot less.

Macro without definition in C

One of the most common case of a macro of this form:

#define _M(x) x

is to provide backwards compatibility for compilers that only supported the original K&R dialect of C, that predated the now-ubiquitous ANSI C dialect. In the original K&R dialect of the language, function arguments were not specified when declaring the function. In 1989, ANSI standardized the language and incorporated a number of improvements, including function prototypes that declared the number of type of arguments.

int f(int x, double y); /* ANSI C. K&R compilers would not accept this */

int f(); /* Function declared in the original K&R dialect */

While compilers that support the original K&R dialect of C are rare (or extinct) these days, a lot of software was written when both kinds of compilers needed to be supported, and macros provided an easy way to support both. There are still a lot of headers laying about that provide this backwards compatibility.

To provide backwards compatibility for K&R compilers, many header files have the following:

#if ANSI_PROTOTYPES
# define _P(x) x
#else
# define _P(x) ()
#endif

...

int f _P((int x, double y));

If the ANSI_PROTOTYPES definition has been correctly set (either by the user or by some prior #ifdef logic), then you get the desired behavior:

  • If ANSI_PROTOTYPES is defined, the definition expands to int f(int x, double y).
  • If ANSI_PROTOTYPES is not defined, the definition expands to int f()

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.



Related Topics



Leave a reply



Submit