【问题标题】:Error "sigemptyset was not declared in this scope" when using C+11 and Newlib使用 C+11 和 Newlib 时出现错误“sigemptyset 未在此范围内声明”
【发布时间】:2016-10-04 05:52:40
【问题描述】:

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

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

我尝试过#define _GNU_SOURCE#define _XOPEN_SOURCE 700 之类的技巧。我还尝试过使用 global 和 std 命名空间等技巧。相关,请参阅What does -D_XOPEN_SOURCE do/mean?Namespace issues in 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);
            ^

Things get worse when using -std=gnu++03 and friends.

【问题讨论】:

  • 我的?当您使用没有 GNU 扩展的普通 C++ 标准时,您需要在包含 &lt;signal.h&gt; 之前定义 _XOPEN_SOURCE
  • 另外,您应该在&lt;cygwin/signal.h&gt; 中查找 Cygwin 信号头文件。
  • 谢谢@Joachim。当 grep 为 sigemptyset 时,有两个命中:(1) /usr/include/bash/sig.h 和 (2) /usr/include/sys/signal.h
  • 我没有告诉你直接包含&lt;cygwin/signal.h&gt;,而是你需要查看Cygwin特定内容的文件。例如,在包含 &lt;signal.h&gt; 之前需要定义哪些宏。

标签: c++ c++11 cygwin signals newlib


【解决方案1】:

该函数是对 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 缩小了定义范围

【讨论】:

  • 感谢 Matzeri。问题浮出水面的方式很有趣。似乎一切都应该失败,或者一切都应该成功。至少,-std=gnu++XX 似乎应该与 -std 一起编译,因为 ISO C 都不是。如果我没记错的话,使用 GCC 的 C++ 编译器时,一些 -std=gnu++XX 是默认值。我猜它是 newlib 做事的方式,因为它不存在于 libstdc++ 中。
  • newlib 标头正在重新洗牌。过去几个月发生了显着变化,/usr/include/sys/features.h 提供了当前指南。
  • 所以....有什么解决办法?
  • @Rebroad #define _GNU_SOURCE 应该可以拥有最大的范围。
【解决方案2】:

问题已在Botan 2.1.0 does not compile under Cygwin 2.8.0 with g++ 5.4.0 得到解决。这是两个感兴趣的 cmets。

首先,来自noloader

Cygwin 使用 Newlib,而不是 GNU 的 libstdc++。没有的时候 -std=c++XX,当前 GCC 默认为 -std=gnu++11(默认为 GCC 6 changes to gnu++14)。一世 相信 GNU 源代码可以确保预期的功能,如 sigaction,是 可用。

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

另见C++ and feature guards Warning Question Newlib 邮件列表。

第二,来自SideChannel

感谢@noloader。到目前为止,-std=c++11 被设置在 Makefile 中。这 重要信息在 Newlib 邮件的上述线程中 列表。 Yaakov Selkowitz 写道:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-20
    • 1970-01-01
    相关资源
    最近更新 更多