目前在 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");
| ^~~~~
uj5u.com熱心網友回復:
#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)
https://godbolt.org/z/srExevfGT
uj5u.com熱心網友回復:
在標準 C 中,;標記表示運算式的結束。因此,括號不能包含 a ;,因為從語法上來說,括號的 a(和a 都)需要在完整的運算式中。
這({ ... })是一個“陳述句運算式”,一個非標準的 GNU 擴展,它允許多個運算式以其中結尾,;同時回傳最后一個運算式的結果。
在-std=c17 -pedantic模式下,gcc 變成了兼容的 C 編譯器,因此所有 GNU 擴展都被禁用。
請注意,可以使用標準 C 代替這些“陳述句運算式”。您通常可以使用逗號運算子鏈接一堆函式呼叫:(perror(m), exit(1))- 這也回傳最后一個(最右邊)子運算式的結果。
更好的是,使用一個實際的函式,這可能是這種情況下最正確的解決方案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/439323.html
上一篇:Free()不釋放記憶體
下一篇:如何替換c中的goto部分
