首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在宏中使用多个函数?

如何在宏中使用多个函数?
EN

Stack Overflow用户
提问于 2022-03-07 11:44:58
回答 2查看 139关注 0票数 0

目前,在c.中构建一个简单的use服务器,为了改进代码,我想要使用makros,而且我希望在单个makro中使用多个函数来打印错误消息,然后退出程序。

下面的代码在没有繁琐的错误信息的情况下工作,但是我想知道为什么ISO-C禁止这样做,或者我的错误在哪里。

编译器信息:

代码语言:javascript
运行
复制
gcc -O0 -g3 -pedantic -pedantic-errors -Wall -Wextra -Werror error_makro.c

代码:

代码语言:javascript
运行
复制
#define CHECK(x,m) ((x) < 0) ? ({perror(m); exit(1);}) : (NULL)

void createWebSocket(simpleWebServer *self){

    struct addrinfo hints, *res;
    memset(&hints, 0, sizeof(hints));

    hints.ai_family = AF_UNSPEC;
    hints.ai_flags = AI_PASSIVE;
    hints.ai_socktype = SOCK_STREAM;


    CHECK(getaddrinfo(NULL, self->port, &hints, &res), "getaddrinfo");

    if((self->serverSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0){
        perror("socket");
        exit(2);
    }
    if(bind(self->serverSocket, res->ai_addr, res->ai_addrlen) < 0){
        perror("bind");
        exit(3);
    }
    if(listen(self->serverSocket, BACKLOG) == -1){
        perror("listen");
        exit(4);
    }
    freeaddrinfo(res);  
}

错误消息:

代码语言:javascript
运行
复制
error_makro.c: In function ‘main’:
error_makro.c:6:32: error: ISO C forbids braced-groups within expressions [-Wpedantic]
    6 | #define CHECK(x,m) ((x) < 0) ? ({perror(m); exit(1);}) : (NULL)
      |                                ^
error_makro.c:11:5: note: in expansion of macro ‘CHECK’
   11 |     CHECK(-1, "test");
      |     ^~~~~
error_makro.c:6:56: error: ISO C forbids conditional expr with only one void side [-Wpedantic]
    6 | #define CHECK(x,m) ((x) < 0) ? ({perror(m); exit(1);}) : (NULL)
      |                                                        ^
error_makro.c:11:5: note: in expansion of macro ‘CHECK’
   11 |     CHECK(-1, "test");
      |     ^~~~~
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-03-07 11:55:37

代码语言:javascript
运行
复制
#define CHECK(x,m) ((x) < 0) ? ({perror(m); exit(1);}) : ({(NULL);})

将发挥作用:

https://godbolt.org/z/Kxed3b55r

两边都有相同类型的void。不能使用-pedantic作为编译时标志,因为ISO C forbids braced-groups within expressions

在这种情况下,我建议:

代码语言:javascript
运行
复制
#define CHECK(x,m) do { if ((x) < 0) {perror(m); exit(1);} } while (0)

https://godbolt.org/z/srExevfGT

票数 1
EN

Stack Overflow用户

发布于 2022-03-07 11:58:52

在标准C中,;标记表达式的结束。因此,括号不能包含;,因为从语法上看,圆括号的()都必须在完整表达式中。

({ ... })是一个“语句表达式”,这是一个非标准的GNU扩展,它允许多个表达式以;结尾,同时返回最后一个表达式的结果。

-std=c17 -pedantic模式下,gcc变成了一个兼容的C编译器,所以所有的GNU扩展都被禁用了。

请注意,可以使用标准C来代替这些“语句表达式”。您通常可以使用逗号运算符:(perror(m), exit(1))链接一系列函数调用--这也会返回最后一个(最右)子表达式的结果。

更好的是,使用一个实际的函数,在这种情况下,这可能是最正确的解决方案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71380582

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档