Extending macros using the ## operator

Hi everyone, the problem is what I have in this macro

 #define ADD_COMP(s1,s2,type)({\
  int _x=0;\
  for(int i=0;i<n_addrs;i++){\
    if(memcmp(s1,&(s2->##type),6)!=0){\
      _x=-1;\
    }else{\
      break;\
    }\
  }\
  _x;\
})

s1 is a simple array, and s2 is a structure with 4 vectors as members like this

typedef struct example{
 char[6] one,
 char[6] two,
 char[6] three
}example;

Now for my own reason, I need to create a function that compares the s1 array of 6 bytes with only a member of the example, so for this purpose I wrote ADD_CMP using the ## operator to be as general as possible. So, I defined:

#define one
#define two
#define three

and I used the function different times this way, hoping for macro success

ADD_COMP(some_array,example1,one)
ADD_COMP(some_array,example1,two)
ADD_COMP(some_array,example1,three)

but the compiler returns as an error:

error: pasting "->" and "one" does not give a valid preprocessing token
error: pasting "->" and "two" does not give a valid preprocessing token
error: pasting "->" and "three" does not give a valid preprocessing token

How can I fix this without writing the same function for each member of the structure?

+4
source share
3 answers

, . , -

#define Glue(x) x my##x_

Glue(int);

:

int my_int;

"my_" "int", "my_int", , .

, , , , . , . , :

#define BadAdd(x, y) x##+##y
int z = BadAdd(137, 42);

, 137+42. , , . C ++ (137, + 42), , , .

Add, :

#define Add(x, y) x + y
int z = Add(137, 42);

Add (137, 42) (137, +, 42), .

, , BadAdd. → , , ->one, . ## - , BadAdd Add, , , .

+3

, ##, .

#define VAR(name, num) name##num
int VAR(foo, 1);  // foo and 1 must be pasted together as foo1, instead of foo 1

 #include<stdlib.h>
 #include<string.h>

 int n_addrs = 6;

 #define ADD_COMP(s1,s2,type) {\
  int _x=0;\
  for(int i=0;i<n_addrs;i++){\
    if(memcmp(s1,&(s2->type),6)!=0){\
      _x=-1;\
    }else{\
      break;\
    }\
  }\
  _x;\
}

typedef struct example{
 char one[6];
 char two[6];
 char three[6];
}example;

void foo(void)
{
    example* example1 = malloc(sizeof(example));
    char some_array[6];
    ADD_COMP(some_array,example1,one)
    ADD_COMP(some_array,example1,two)
    ADD_COMP(some_array,example1,three)
}

{ ... } . , gnu C.

, . _x , .

+5

, pre-processor ##.

:

#define ADD_COMP(s1, s2, member) ({\
  int _x = 0;\
  for (int i = 0; i < n_addrs; i++){\
    if(memcmp(s1, &(s2.member), 6) !=0 ){\
      _x = -1;\
    } else {\
      break;\
    }\
  }\
  _x;\
})

:

ADD_COMP(some_array,example1,one);
ADD_COMP(some_array,example1,two);
ADD_COMP(some_array,example1,three);

, , , , , . , , , n_addrs _x.

0

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


All Articles