42

我有一个项目可以在 g++ 4.8.1 和 clang >= 3.3 下在 c++11 模式下正确编译和运行。但是,当我切换到实验-std=c++1y模式时,clang 3.3(但不是 g++)会阻塞<cstdio>通过 Boost.Test 间接包含的标题(所以我自己不能轻易更改它)

// /usr/include/c++/4.8/cstdio
#include <stdio.h>

// Get rid of those macros defined in <stdio.h> in lieu of real functions.
// ...
#undef gets
// ...    

namespace std
{
// ...
using ::gets; // <-- error with clang++ -std=c++1y
// ...
}

带有以下错误消息:

/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/cstdio:119:11:错误:全局中没有名为“gets”的成员命名空间

这个关于如何设置现代 C++ 环境的教程中,max_align_t遇到了类似的查找问题。那里的建议是使用 sed 脚本用#ifdef __clang__宏包围未知符号,但这似乎是一种脆弱的方法。

设置:普通的 64 位 Linux Mint 15

g++ (Ubuntu 4.8.1-2ubuntu1~13.04) 4.8.1

Ubuntu clang 版本 3.3-3~raring1 (branches/release_33) (基于 LLVM 3.3)

问题

  • 是什么导致了这个错误?有__clang__问题的代码附近没有宏,c++11模式下的clang一点问题都没有。
  • 这是一个语言问题(C++14 是否说 C++11 之外的其他内容,关于将 C 兼容符号从全局导入std命名空间)?
  • 我需要用我的包含路径改变一些东西吗?(我使用 CMake 自动选择标题路径,并在 CMakeLists.txt 中切换模式)
  • 铿锵有开关来解决这个问题吗?
4

1 回答 1

23

手册页中的此注释gets看起来很相关:

_ISOC11_SOURCEISO C11 从 C 语言中删除了 gets() 的规范,并且从 2.16 版开始,如果定义了功能测试宏,glibc 头文件不会公开函数声明。

大概应该是

#if !_ISOC11_SOURCE
using ::gets;
#endif
于 2013-07-21T20:25:02.087 回答