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

时间:2014-09-23 23:43:24

标签: c++ gcc c++11 centos 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));
                 ^

什么?

我使用的命令是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;
}

详情

我正在使用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)

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进行调试以获取更多信息...这提供了一些线索,但我不知道从哪里开始。

群集1上的中间(.ii)文件缺少某些行,例如(摘自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;
---
> 
> 
>

正如我所解释的那样,两个群集上的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

我很好奇,如果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.

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

非常感谢任何更多的线索或见解。

2 个答案:

答案 0 :(得分:4)

您已经完成了所有必要的步法以确定根本原因。您已经知道答案:您已经发布了自定义gcc安装在您的&#34;集群1&#34;和#34;集群2&#34;,一个非工作和工作的构建。

因此,这两个gcc安装之间的区别明显不同;如果一个编译,链接,并运行一些代码,另一个扼杀相同的代码片段。不幸的是,很难确定哪些事情发生了变化。之前我自己构建了gcc,我可以说gcc是一个非常难以安装且非常易变的软件包。例如,在连接一些C ++代码后几天追逐一个神秘的失败后,我最终追逐到gcc拿起错误版本的binutils,在gcc的配置脚本中,并在内部关闭一些不起眼的功能,最终表现为链接失败不是gcc,而是用gcc构建的东西。 gcc本身已经建成并安装了,没有任何投诉,但它被打破了。

所以,我发现gcc本身在没有明显问题的情况下构建和安装的命题完全不足为奇,而且完全合情合理,但它已经破碎了,并且会以这种方式阻塞有效代码。

我的猜测是你破坏的gcc版本使用了一个破坏的默认包含路径 - 它在/usr/include中寻找标题,而不是你自己的自定义安装目录。这是最可能的答案,但它确实可以是任何东西。

答案 1 :(得分:1)

嗯,你很明显(就像你自己写的那样)两个不同的gcc(一次4.4.7-3和另一个4.4.7-4),似乎他们有(尽管有点)差异编译代码。

正如我在某处读到的那样,C ++ 11标准尚未完全包含在所有编译器中,因此这似乎是一个集群的原因。另一个(你可能知道为什么)包含更多新标准的版本,因为你想要使用这个功能,我建议在其他集群上安装这个版本。

相关问题