When and why use macroC # define (x) instead of a function?

Seeing this question , I asked myself the question why the approach (example of a toy):

#define foo(x) bar[x] = 0

functions will always be preferable:

void foo(unsigned x){ bar[x] = 0; }

Before the question related above, I saw this before, in the PolarSSL library, where I assumed that it was some kind of optimization, and tried not to think too much about it.

I assume that using the preprocessor macro replaces the “call” with the “body of nothingness” wherever it exists; while a function voidmay be optimized by the compiler or may not be optimized, and therefore may result in a large fork for a small and simple operation or two.

Are there any other benefits?

When is it preferable to use the macro method, and when is it best to trust the compiler?

+4
source share
3 answers

First, I hope your macro was actually:

#define foo(x) do { bar[x] = 0; } while (0)

for proper smoothing with a comma .

One thing in favor of macros is that you think your compiler optimizer is not good enough. You may be mistaken. But if you have really studied the conclusion carefully and know what you are doing, you are probably right, which is why it is often used in the Linux kernel.

Another reason is that macros are faceless, so you can:

#define foo(x,t) do { t[x] = 0; } while (0)

t. , , .

+2

. . , .

#define ENCODED(a,b,c,d) (((((((a)<<8)+b)<<8)+c)<<8)+d)

switch (a) {
   case ENCODED('f','o','o','0'):   ...
   case ENCODED('b', 'a', 'r', '1'): ...
}

:

#define LIB_VERSION v101
#define VERSIONNED(x) x##LIB_VERSION

void VERSIONNED(myfunction)(int x) { ... }

"". :

#define assert(x) {if ((x) == 0) {printf("%s:%d: Assertion %s failed\n", __FILE__, __LINE__, #x); exit(-1); }}

"" , . :

#define DELETE_LAST_ITEM(x) {while (x->next->next != NULL) x=x->next ; x->next = NULL}

, , , .

+4

?

. __LINE__ __FILE__, , .

#define foo(x) bar[x] = 0; PrintFunction("...", __FILE__,__LINE__)

, .

, ?

, , , .

+3

Source: https://habr.com/ru/post/1568541/


All Articles