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

7
我们在使用Newlib下的Cygwin时,遇到了在使用sigemptyset时出现编译错误的情况。该错误只在使用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);
}

如果没有使用-std=XXX,将会导致:

$ g++ -c test.cxx
$

使用-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);

当尝试在全局命名空间中使用 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);
            ^

使用-std=gnu++03及其相关选项会使情况变得更糟。


我的猜测是,当您使用不带GNU扩展的纯C++标准时,在包含<signal.h>之前需要定义“_XOPEN_SOURCE”。 - Some programmer dude
此外,您应该查找 <cygwin/signal.h> 以获取 Cygwin 信号头文件。 - Some programmer dude
谢谢@Joachim。当使用grep查找sigemptyset时,有两个匹配项:(1)/usr/include/bash/sig.h和(2)/usr/include/sys/signal.h - jww
我没有告诉你直接包含 <cygwin/signal.h>,而是这是一个你需要查看的文件,用于处理Cygwin特定的事情。例如,在包含 <signal.h> 之前需要定义哪些宏。 - Some programmer dude
2个回答

2

谢谢Matzeri。问题出现的方式很有趣。似乎一切都应该失败,或者一切都应该成功。至少,似乎-std=gnu++XX应该与没有-std一起编译,因为两者都不是ISO C。如果我没记错的话,使用GCC的C++编译器时,一些-std=gnu++XX是默认的。我猜这是newlib做事情的方式,因为它在libstdc++中不存在。 - jww
newlib头文件正在重新整理。在过去的几个月中有显著的更改,/usr/include/sys/features.h提供了当前的指南。 - matzeri
那么......解决方案是什么? - Rebroad
1
@Rebroad #define _GNU_SOURCE应该可以扩大作用范围。 - matzeri

1
这个问题已在 Botan 2.1.0在使用g++ 5.4.0编译Cygwin 2.8.0时无法编译 中得到解决。以下是两个相关的评论。
第一个来自noloader
Cygwin使用Newlib,而不是GNU的libstdc ++。当没有-std=c++XX时,当前的GCC默认为-std=gnu++11GCC 6更改默认为 gnu++14 )。我相信GNU源代码确保了可用的预期函数,如sigaction等。

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

另请参见Newlib邮件列表中有关C ++和特征保护警告问题的讨论

第二个问题来自SideChannel

感谢@noloader。直到现在,Makefile中设置了-std=c++11。重要的信息在Newlib邮件列表上提到的线程中。Yaakov Selkowitz写道:

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接