目前,在c.中构建一个简单的use服务器,为了改进代码,我想要使用makros,而且我希望在单个makro中使用多个函数来打印错误消息,然后退出程序。
下面的代码在没有繁琐的错误信息的情况下工作,但是我想知道为什么ISO-C禁止这样做,或者我的错误在哪里。
编译器信息:
gcc -O0 -g3 -pedantic -pedantic-errors -Wall -Wextra -Werror error_makro.c
代码:
#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);
}
错误消息:
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");
| ^~~~~
发布于 2022-03-07 11:55:37
#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
。
在这种情况下,我建议:
#define CHECK(x,m) do { if ((x) < 0) {perror(m); exit(1);} } while (0)
发布于 2022-03-07 11:58:52
在标准C中,;
标记表达式的结束。因此,括号不能包含;
,因为从语法上看,圆括号的(
和)
都必须在完整表达式中。
({ ... })
是一个“语句表达式”,这是一个非标准的GNU扩展,它允许多个表达式以;
结尾,同时返回最后一个表达式的结果。
在-std=c17 -pedantic
模式下,gcc变成了一个兼容的C编译器,所以所有的GNU扩展都被禁用了。
请注意,可以使用标准C来代替这些“语句表达式”。您通常可以使用逗号运算符:(perror(m), exit(1))
链接一系列函数调用--这也会返回最后一个(最右)子表达式的结果。
更好的是,使用一个实际的函数,在这种情况下,这可能是最正确的解决方案。
https://stackoverflow.com/questions/71380582
复制相似问题