g ++不包含它为C++ 11包含的文件?

and*_*ras 8 c++ gcc centos c++11 centos6.5

精简版

当我使用C++ 11标准(该std::stod函数)的特性编译一个简单的代码时,GCC 4.9.1失败并出现以下错误:

example.cpp: In function 'int main()':
example.cpp:10:18: error: 'stod' is not a member of 'std'
   double earth = std::stod (orbits,&sz);
                  ^
example.cpp:11:17: error: 'stod' is not a member of 'std'
   double moon = std::stod (orbits.substr(sz));
                 ^
Run Code Online (Sandbox Code Playgroud)

什么?

我使用的命令是g++ -std=c++11 example.cpp.

这是测试代码(在其他系统上编译良好):

// stod example from http://www.cplusplus.com/reference/string/stod/
#include <iostream>   // std::cout
#include <string>     // std::string, std::stod

int main ()
{
  std::string orbits ("365.24 29.53");
  std::string::size_type sz;     // alias of size_t

  double earth = std::stod (orbits,&sz);
  double moon = std::stod (orbits.substr(sz));
  std::cout << "The moon completes " << (earth/moon) << " orbits per Earth year.\n";
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

细节

我正在使用GCC 4.9.1的一个版本我在运行CentOS 6.5的两个不同的集群上编译自己(因为我不是管理员,所以在我的家庭目录中使用模块系统).

我将其称为集群1和集群2:集群1是故障发生的地方.

GCC以相同的方式同时编译,并使用相同的模块文件加载(除了基本路径的微小差异).就我可以轻松检查而言,安装是相同的(两个集群上都存在相同的包含文件,并且具有相同的内容).

g++ -v两个集群的输出相同(同样,安装路径除外):

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/home/andyras/bin/gcc-4.9.1/libexec/gcc/x86_64-unknown-linux-gnu/4.9.1/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-4.9.1/configure --prefix=/home/andyras/bin/gcc-4.9.1 --enable-languages=c,c++,fortran
Thread model: posix
gcc version 4.9.1 (GCC)
Run Code Online (Sandbox Code Playgroud)

g++ -v使用系统GCC在两个集群上都提供相同的输出,除了在集群1上它表示它gcc version 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC)并且在集群2上说gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)

我正在尝试调试使用g++ -std=c++11 -save-temps -MD example.cpp更多信息......这提供了一些线索,但我不知道从哪里开始.

中间体(.ii第1组)的文件丢失一些线,例如(摘自diff荷兰国际集团的.ii文件):

< # 277 "/opt/gcc-4.9.1/include/c++/4.9.1/cwchar" 3
---
> # 277 "/home/andyras/bin/gcc-4.9.1/include/c++/4.9.1/cwchar" 3
961,963c934,936
<   using std::wcstold;
<   using std::wcstoll;
<   using std::wcstoull;
---
> 
> 
>
Run Code Online (Sandbox Code Playgroud)

正如我所解释的那样,两个集群上的GCC都试图包含类似的文件cwchar,但是在集群1上有空行而不是定义的东西.在群集2上,stod功能位于中间文件中,但不在群集1上.

它可能是预处理器错误吗?

现在看一下.d(依赖)文件,我也看到了一个具体的区别.群集2上列出的某些文件未在群集1上列出.这是列表(我处理了.d文件的内容以考虑不同的基本路径; //代表安装路径):

85a86,108
> //gcc-4.9.1/include/c++/4.9.1/ext/string_conversions.h
> //gcc-4.9.1/include/c++/4.9.1/cstdlib
> /usr/include/stdlib.h
> /usr/include/bits/waitflags.h
> /usr/include/bits/waitstatus.h
> /usr/include/sys/types.h
> /usr/include/sys/select.h
> /usr/include/bits/select.h
> /usr/include/bits/sigset.h
> /usr/include/sys/sysmacros.h
> /usr/include/alloca.h
> //gcc-4.9.1/include/c++/4.9.1/cstdio
> /usr/include/libio.h
> /usr/include/_G_config.h
> /usr/include/bits/stdio_lim.h
> /usr/include/bits/sys_errlist.h
> //gcc-4.9.1/include/c++/4.9.1/cerrno
> /usr/include/errno.h
> /usr/include/bits/errno.h
> /usr/include/linux/errno.h
> /usr/include/asm/errno.h
> /usr/include/asm-generic/errno.h
> /usr/include/asm-generic/errno-base.h
Run Code Online (Sandbox Code Playgroud)

我很好奇,如果cpp在所有错误的地方寻找包括,但这似乎合法(cpp -v):

#include <...> search starts here:
 /home/andyras/bin/gcc-4.9.1/include
 /home/andyras/bin/gcc-4.9.1/include/c++/4.9.1/
 /home/andyras/bin/gcc-4.9.1/include/c++/4.9.1/x86_64-unknown-linux-gnu/
 /home/andyras/bin/gcc-4.9.1/lib/gcc/x86_64-unknown-linux-gnu/4.9.1/include
 /usr/local/include
 /home/andyras/bin/gcc-4.9.1/lib/gcc/x86_64-unknown-linux-gnu/4.9.1/include-fixed
 /usr/include
End of search list.
Run Code Online (Sandbox Code Playgroud)

这是一个非常令人沮丧的几个小时试图追查问题的根源.当然,我可以使用类似的东西atof(myString.c_str())而不是std::stod,但我想知道是否存在一个潜在的问题,将使用C++ 11的其他部分来破坏未来的项目.

任何更多的线索或见解将非常感激.

Sam*_*hik 4

您已经完成了所有必要的步骤来确定根本原因。您已经知道答案:您已经发布了自定义 gcc 安装在“集群 1”和“集群 2”(非工作构建和工作构建)上的行为之间的明显差异。

所以,这两个 gcc 安装之间显然有一些不同;如果一个人编译、链接并运行一些代码,而另一个人却因完全相同的代码而窒息。不幸的是,很难确定事情出轨的地方。以前我自己构建过 gcc,我可以说 gcc 是一个非常难以安装且变化无常的软件包。例如,在链接一些 C++ 代码时,经过几天的追踪一个神秘的失败,我最终追踪到 gcc 在 gcc 的配置脚本中选择了错误版本的 binutils,并在内部关闭了一些晦涩的功能,最终表现为不是 gcc 的链接失败,而是使用 gcc 构建的东西的链接失败。gcc 本身被构建并安装,没有任何抱怨,但它被破坏了。

因此,我发现 gcc 本身的构建和安装没有明显问题的主张完全不足为奇,而且完全合理,但它已损坏,并且会以这种方式被有效代码阻塞。

我的猜测是,您损坏的 gcc 构建正在使用损坏的默认包含路径 - 它正在寻找 中的标头/usr/include,而不是您自己的自定义安装目录。这是最有可能的答案,但也可能是任何东西。