【问题标题】:How to append to the name of an argument in C macro如何附加到 C 宏中的参数名称
【发布时间】:2014-06-24 03:49:55
【问题描述】:

我有一个奇怪的用例,我需要修改在 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);  
 }

因为我在一个protocol buffer消息中使用了repeated type,所以可变长度定义为

n_variable_name

而不是

variable_name.len

例如。

variable_name = frequency

// the length have to be n_frequency

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

任何建议将不胜感激

谢谢

【问题讨论】:

  • 尝试使用## 连接运算符。这样:msg_ptr->n_##field_name = src_data_length;
  • @Don'tYouWorryChild:我很确定反斜杠后不应后跟空格或换行符以外的任何内容。
  • @jwodder:是的!谢谢你的提醒。我很困惑,实际上我曾经在反斜杠后放置空格时遇到过这个问题,我花了一些时间才弄清楚。直到我读到你的评论之前,我记得相反!! :-)

标签: c protocol-buffers


【解决方案1】:

编写多行宏的规范方法是将其包装在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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-18
    • 2018-09-11
    • 1970-01-01
    • 1970-01-01
    • 2021-03-23
    • 1970-01-01
    • 2020-11-19
    • 1970-01-01
    相关资源
    最近更新 更多