使用类似函数的marcos,有什么问题吗?

时间:2013-03-26 11:02:20

标签: c optimization

gcc 4.7.2
c89

您好,

类似函数的宏只是文本替换,我知道一些程序员更喜欢内联函数。我想知道我所做的事情是否有任何问题。

请注意几点,我没有使用do ... while(0)或花括号来包装,因为我会得到isdn_channel的非声明错误。

#define ISDN_CHANNEL_GET(channel)                                       \
    module_isdn_channel_t *isdn_channel = NULL;                         \
    isdn_channel = channel->base.imp->isdn_channels[channel->isdn_id];  \
    if(!isdn_channel) {                                                 \
        LOG(CRITICAL, "Failed to get channel data");                    \
        return FALSE;                                                   \
    }  

在我的源代码中,我像这样使用它,没有添加分号:

ISDN_CHANNEL_GET(channel)
isdn_channel->base.sync_answer |= SIP_CONNECTED;

一切正常,但我只是想检查一下,我正在编写这些类似函数的宏。

非常感谢任何建议,

4 个答案:

答案 0 :(得分:3)

请不要在宏中使用return。

正如我们所知,Macros告诉预处理器替换#define之后的任何内容。

所以你可能会在一个函数中间不知不觉地返回

答案 1 :(得分:3)

只要你不做以下事情就没问题:     如果(条件)     ISDN_CHANNEL_GET(信道)

使用do ... while(0)包裹宏以避免此问题。

答案 2 :(得分:2)

在jbgs和Manimehalai提到的问题之后,还有其他问题:

  • 宏参数的多重评估(这里使用两次)
  • 运算符优先级(始终在参数周围使用括号)
  • 缺少打字(尽可能使用打字,编译器是你的朋友)

前两个是杀手,只要你传递更复杂的表达式作为参数,也可能包含副作用。当你传入一个指向具有相同名称字段的结构的指针时,第三个会向你发送字节,例如,但它会做一些完全不同的事情。

您的示例实际上是编写具有相同功能的inline函数的示例。如果你这样做,编译器可以帮助你调试你的代码,总是使用编译器,而不是反对它。

答案 3 :(得分:1)

每当你call这个类似函数的宏时,它就会被扩展 - 你优化时间而不是空间:-)。它在编译时肯定会扩展你的应用程序的大小。

我的第一条法则:“你可以优化空间或优化时间 - 但不能兼顾空间和时间”