1
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

4 回答 4

3

请不要在宏中使用 return。

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

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

于 2013-03-26T11:06:53.190 回答
3

只要您不执行以下操作就没有问题: if (condition) ISDN_CHANNEL_GET(channel)

用 do...while(0) 包装你的宏以避免这个问题。

于 2013-03-26T11:06:54.513 回答
2

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

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

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

您的示例确实是编写inline具有相同功能的函数是微不足道的。如果您愿意,编译器可以帮助您调试代码,始终使用编译器而不是反对它。

于 2013-03-26T14:26:09.597 回答
1

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

我的第一定律:“你可以优化空间或优化时间——但不能同时优化空间和时间”

于 2013-03-26T11:05:40.713 回答