7

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

测试程序如下,感兴趣的 Cygwin 标头如下。我在 Cygwin 标题中没有看到任何可疑之处。

我尝试过像#define _GNU_SOURCEand之类的技巧#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);
}

没有 a -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和朋友时情况变得更糟。

4

2 回答 2

2

该函数是对 ISO C 标准的扩展。
http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigemptyset.html

因此受到 /usr/include/sys/signal.h__XSI_VISIBLE
>= 4的保护

详情见 /usr/include/sys/features.h

默认使用最大的定义集,但-std=XXX会缩小定义范围

于 2016-10-05T04:54:54.873 回答
1

该问题已在Botan 2.1.0 does not compile under Cygwin 2.8.0 with g++ 5.4.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。直到现在-std=c++11被设置在Makefile. 重要信息在上面提到的 Newlib 邮件列表中。雅科夫塞尔科维茨写道:

G++_GNU_SOURCE在 glibc 目标上定义,也就是说-std=c++NN,与文档相反,不是严格的 ISO C++:

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

于 2017-05-27T03:13:55.577 回答