如何附加到C宏中的参数名称

时间:2014-06-24 03:49:55

标签: c protocol-buffers

我有一个奇怪的用例,我需要修改在C中传递的变量的名称

#define SET_PROTOBUF_REPEATED(msg_ptr, field_name, src_data, src_data_length) 
{     
 /*
 msg_ptr->field_name.len = src_data_length;   
 */     

 // I want to do this
 // msg_ptr->n_field_name = src_data_length 

 /*
 msg_ptr->field_name.data = malloc(src_data_length);    
 memcpy(msg_ptr->field_name.data, src_data, src_data_length);     
 */
 msg_ptr->field_name = malloc(src_data_length);    
 memcpy(msg_ptr->field_name, src_data, src_data_length);  
 }

因为我在协议缓冲区消息中使用重复类型,所以可变长度定义为

n_variable_name

而不是

variable_name.len

例如

variable_name = frequency

// the length have to be n_frequency

我想要有一个宏来执行此操作的原因是因为我有很多protobuf消息重复上述函数的功能。为了便于阅读和模块化,我认为定义一个能够解决这个问题的新功能是个好主意。

非常感谢任何建议

由于

1 个答案:

答案 0 :(得分:2)

编写多行宏的规范方法是将其包装在do ... while(0)语句中。这可以确保宏作为单个语句工作。例如:

#define macro(a,b,c) \
  do { \
    (a) = (b)*(c); \
  } while (0)  /* No trailing semi-colon */

...

macro (x, y, z);
for (i = 0; i < n; i++)
  macro (x, y, z);  /* This wouldn't work properly without do...while(0) */

您应该在宏参数周​​围加上括号,以避免在有人传递意外参数时出现意外,例如macro (t, 1+2, 3+4);您还需要一个辅助宏来连接参数。也许你正在寻找这样的东西:

#define CONCAT(x,y) x ## y

#define SET_PROTOBUF_REPEATED(msg_ptr, field_name, src_data, src_data_length) \
do {                                                      \
  (msg_ptr)->CONCAT(n_,field_name) = (src_data_length);   \
                                                          \
  (msg_ptr)->(field_name) = malloc((src_data_length));            \
  memcpy((msg_ptr)->(field_name), (src_data), (src_data_length)); \
} while (0)