Need help defining macros

Im reading C ++ code, I found such a definition

#define USE_VAL(X) if (&X-1) {} 

have an idea what does this mean?

+6
source share
3 answers

Based on the name, it looks like a way to get rid of the "unused variable" warning. The intended use is probably something like this:

 int function(int i) { USE_VAL(i) return 42; } 

Without this, you can get a compiler warning that the i parameter is not used inside the function.

However, this is a rather dangerous way to get around this, because it injects Undefined Behavior into the code (pointer arithmetic outside the actual Undefined array by standard). You can add 1 to the address of the object, but do not subtract 1. Of course, instead of + 1 instead of - 1 compiler could warn that the condition is always true. The optimizer may delete the entire if and the code will remain valid, but the optimizers will improve when using the “undefined behavior cannot happen”, which can really spoil the code completely unexpectedly.

Not to mention that operator& can be overloaded for the corresponding type, which could potentially lead to undesirable side effects.

There are more efficient ways to implement functions such as casting in void :

 #define USE_VAL(X) static_cast<void>(X) 

However, my personal preference is to comment on the parameter name in the function definition, for example:

 int function(int /*i*/) { return 42; } 

The advantage of this is that it actually prevents accidental use of the parameter after passing it to the macro.

+7
source

This usually avoids the warning of an unused return value. Even if the usual idiom “cast to void” usually works for unused functional parameters, gcc with -pedantic is especially strict when ignoring return values ​​of functions like fread (in general, functions marked with __attribute__((warn_unused_result)) ), therefore " fake if "is often used to trick the compiler into thinking that you are doing something with the return value.

+1
source

A macro is a preprocessor directive, which means that wherever it is used, it will be replaced by the corresponding code fragment.

and here after USE_VAL (X) the space is explained what USE_VAL (X) will do.

First, it takes the address x, and then subtracts 1. from it. If it is 0, do nothing.

where USE_VAL (X) will be used, it will be replaced by if (& X-1) {}

0
source

All Articles