C - 如何在宏中使用多个函数?
目前正在用 c 构建一个简单的网络服务器。 为了改进代码,我想使用 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");
| ^~~~~
Currently building a simple webserver in c.
To improve the code I want to use makros and spefically I want to use multiple functions inside a single makro to print an error message and quit the program afterwards.
The following code works without pedantic error messages but I would like to know why ISO-C forbids this or where my error is.
Compiler info:
gcc -O0 -g3 -pedantic -pedantic-errors -Wall -Wextra -Werror error_makro.c
Code:
#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 message:
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");
| ^~~~~
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
将起作用:
https://godbolt.org/z/Kxed3b55r
双方具有相同的类型
无效。您不能使用
-pedantic
作为编译时标志,因为ISO C 禁止表达式内使用大括号
。在这种情况下,我建议:
https://godbolt.org/z/srExevfGT
will work:
https://godbolt.org/z/Kxed3b55r
Both sides have the same type
void
. You cannot use-pedantic
as compile time flag, becauseISO C forbids braced-groups within expressions
.In this case I would suggest:
https://godbolt.org/z/srExevfGT
在标准 C 中,
;
标记表达式的结束。因此,括号不能包含;
,因为从语法角度来看,括号的(
和)
都需要位于完整表达式内。({ ... })
是一个“语句表达式”,是一个非标准 GNU 扩展,允许在其中包含多个以;
结尾的表达式,同时返回最后一个表达式的结果。在 -std=c17 -pedantic 模式下,gcc 变成兼容的 C 编译器,因此所有 GNU 扩展都被禁用。
请注意,可以使用标准 C 来代替这些“语句表达式”。您通常可以使用逗号运算符链接一堆函数调用:
(perror(m), exit(1))
- 这也返回最后一个(最右边)子表达式的结果。更好的是,使用实际的函数,这可能是这种情况下最正确的解决方案。
In standard C, the
;
marks the end of an expression. Therefore a parenthesis cannot contain a;
, since syntax-wise a both(
and)
of the parenthesis needs to be inside a full expression.The
({ ... })
is a "statement expression", a non-standard GNU extension that allows multiple expressions ending with;
inside it and at the same time returning the result of the last expression.In
-std=c17 -pedantic
mode, gcc turns into a compliant C compiler so all GNU extensions are disabled.Please note that standard C can likely be used instead of these "statement expressions". You can often chain a bunch of function calls using the comma operator:
(perror(m), exit(1))
- this too returns the result of the last (right-most) sub-expresion.Better yet, use an actual function, which is probably the most correct solution in this case.