我正在尝试struct sigaction
使用C ++ 20指定的初始化程序(从sigaction.h)进行初始化,但是存在编译器错误。由于这是一个较大程序的一部分,因此我创建了一个简短的示例:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void onSIGINT(int signal, siginfo_t *siginfo, void *context) {
printf("Caught signal\n");
}
int main(int argc, char** argv) {
struct sigaction act = {
.sa_sigaction = onSIGINT,
.sa_flags = SA_SIGINFO
};
if(sigaction(SIGINT, &act, nullptr) != 0) {
fprintf(stderr, "Failed to listen for SIGINT\n");
return 1;
}
printf("Waiting for signal...\n");
pause();
printf("Exit\n");
return 0;
}
根据https://gcc.gnu.org/projects/cxx-status.html#cxx20的规定,gcc8中提供了指定的初始化程序。运行g ++(在Debian buster上-std=c++2a
为v8.3.0),则会出现以下错误:
main.cpp: In function ‘int main(int, char**)’:
main.cpp:11:9: error: expected primary-expression before ‘.’ token
.sa_sigaction = onSIGINT,
^
main.cpp:12:9: error: either all initializer clauses should be designated or none of them should be
.sa_flags = SA_SIGINFO
^
仅初始化sa_flags
成功编译,仅初始化sa_sigaction
失败编译(仅第一个错误)。
我也尝试__sigaction_handler
直接初始化(不使用define访问工会成员):
struct sigaction act = {
.__sigaction_handler = { .sa_sigaction = onSIGINT },
.sa_flags = SA_SIGINFO
};
产生类似的错误:
main.cpp: In function ‘int main(int, char**)’:
main.cpp:12:34: error: expected primary-expression before ‘.’ token
.__sigaction_handler = { .sa_sigaction = onSIGINT },
^
我想我在结构内部的联合方面做错了,但我不知道是什么。
我知道我可以通过将结构的内存清零然后设置回调和标志来达到大致相同的效果,但这并不是重点。
问题是这sa_sigaction
是一个宏,定义为__sigaction_handler.sa_sigaction
。这意味着您的代码扩展为.__sigaction_handler.sa_sigaction = onSIGINT
; 这是有效的C,允许命名成员初始化程序具有复杂的结构,但在C ++ 20中无效。
可以看到#undef
它:
#undef sa_sigaction
.__sigaction_handler = { .sa_sigaction = onSIGINT },
但是,这是不可移植的(未定义标准库宏,更不用说使用双下划线前缀成员了),所以我建议不要这样做。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句