Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

noop

One in a while there's a need for a no-op statement in C++. For example when implementing assert() which is disabled in non-debug configuration (also see this question):

#ifdef _DEBUG #define assert(x) if( !x ) { \                      ThrowExcepion(__FILE__, __LINE__);\                   } else {\                      //noop here \                   } #else #define assert(x) //noop here #endif 

So far I'm under impression that the right way is to use (void)0; for a no-op:

(void)0; 

however I suspect that it might trigger warnings on some compilers - something like C4555: expression has no effect; expected expression with side-effect Visual C++ warning that is not emitted for this particular case but is emitted when there's no cast to void.

Is it universally portable? Is there a better way?

like image 401
sharptooth Avatar asked Nov 02 '11 10:11

sharptooth


People also ask

What is a no op in C?

Alternatively known as a do-nothing instruction, the no-operation instruction, NO-OP or NOP instruction in programming tells a program to do nothing if a conditional statement is met. Tip. This term is pronounced as no op.

What is NOP in C programming?

In computer science, a NOP, no-op, or NOOP (pronounced "no op"; short for no operation) is a machine language instruction and its assembly language mnemonic, programming language statement, or computer protocol command that does nothing.

How do you insert an assembly instruction such as NOP in AC program?

A NOP instruction may be inserted by calling the intrinsic function _nop_(). The second method is to use in-line assembler. The Keil tools use a #pragma for inline assembler. To use inline assembler, the Keil compiler must be invoked using SRC directive.

What is a no op build?

A no op (or no-op), for no operation , is a computer instruction that takes up a small amount of space but specifies no operation. The computer processor simply moves to the next sequential instruction. The no op is included in most assembler languages.


2 Answers

The simplest no-op is just having no code at all:

#define noop 

Then user code will have:

if (condition) noop; else do_something(); 

The alternative that you mention is also a no-op: (void)0;, but if you are going to use that inside a macro, you should leave the ; aside for the caller to add:

#define noop (void)0 if (condition) noop; else do_something(); 

(If ; was part of the macro, then there would be an extra ; there)

like image 120
David Rodríguez - dribeas Avatar answered Sep 20 '22 21:09

David Rodríguez - dribeas


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.

like image 21
Steve Jessop Avatar answered Sep 21 '22 21:09

Steve Jessop