使用C + 11和Newlib时出现"在此范围内未声明sigemptyset"错误

jww*_*jww 6 c++ cygwin signals newlib c++11

sigemptyset在Newlib下使用Cygwin 时,我们正在捕获编译器错误.C++编译器发生错误,但仅在-std=XXX使用时发生.如果没有标准选项,测试程序将按预期编译和执行.

测试程序如下,感兴趣的Cygwin标题如下.我没有在Cygwin标题中看到任何可疑的东西.

我曾经尝试过#define _GNU_SOURCE和伎俩#define _XOPEN_SOURCE 700.我也尝试过使用全局和std名称空间等技巧.相关,请参阅-D_XOPEN_SOURCE做什么/意味着什么?c ++ 11中的命名空间问题?.

是什么导致编译失败,我该如何解决?


$ cat ~/test.cxx 
#include <signal.h>

int main(int argc, char* argv[])
{
    struct sigaction new_handler;
    return sigemptyset(&new_handler.sa_mask);
}
Run Code Online (Sandbox Code Playgroud)

如果没有-std=XXX,它会导致:

$ g++ -c test.cxx
$
Run Code Online (Sandbox Code Playgroud)

使用a -std=XXX,它会导致:

$ g++ -std=c++03 -c test.cxx
test.cxx: In function int main(int, char**):
test.cxx:6:44: error: sigemptyset was not declared in this scope
  return sigemptyset(&new_handler.sa_mask);
Run Code Online (Sandbox Code Playgroud)

当尝试sigemptyset在全局命名空间中使用时:

$ g++ -std=c++03 -c test.cxx
test.cxx: In function ‘int main(int, char**)’:
test.cxx:6:12: error: ‘::sigemptyset’ has not been declared
     return ::sigemptyset(&new_handler.sa_mask);
            ^
Run Code Online (Sandbox Code Playgroud)

使用-std=gnu++03和朋友时情况变得更糟.

jww*_*jww 1

该问题已在Botan 2.1.0 无法在 Cygwin 2.8.0 和 g++ 5.4.0 下编译时解决。这是两个有趣的评论。

首先,来自noloader

Cygwin 使用 Newlib,而不是 GNU 的libstdc++. 当没有 时 -std=c++XX,当前的 GCC 默认为-std=gnu++11( GCC 6默认更改为)。gnu++14我相信 GNU 源代码确保了预期的功能,例如sigaction,可用。

您可以考虑尝试-D_XOPEN_SOURCE=600-D_XOPEN_SOURCE=700

另请参阅Newlib 邮件列表上的C++ 和功能防护警告问题。

其次,来自SideChannel

感谢@noloader。直到现在-std=c++11才被设定Makefile。重要信息位于上面提到的 Newlib 邮件列表中。雅科夫·塞尔科维茨写道:

_GNU_SOURCEG++在 glibc 目标上定义,这意味着-std=c++NN与文档相反,G++ 不是严格的 ISO C++:

因此,应用补丁 #987 和设置-std=gnu++11对我有用。我没有尝试其他-D选项(我认为另一个事实更基本)。总结一下,@randombit 请应用 PR #987 并 -std=gnu++11在 Cygwin 下为 gcc 设置。