【发布时间】:2014-11-18 07:48:15
【问题描述】:
短版
当我使用 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) 文件缺少一些行,例如(摘自 diffing .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 其他位的未来项目。
非常感谢任何更多的线索或见解。
【问题讨论】:
-
前段时间我也遇到过同样的问题,这是因为我遗漏了“-std=c++11”。我知道你说你有那个,但也许再检查一下?
-
也许可以试试“-std=c++0x”。以防万一。
-
我会检查你的路径。作为一个实验,我在我的 Debian 系统上加载了 g++-4.4,并尝试在没有 -stdc=c++11 标志的情况下编译 example.cpp,它就像你的一样在 stod 上窒息。我会验证您在编译时实际上使用的是正确的 g++ 编译器。如果我使用我的 g++-4.7 它工作正常。
-
我确实在使用我认为的 GCC 版本......有趣的是它在同一系统上与 GCC 4.8.3 一起工作正常。
-
狂拍:在你的 4.4.7 安装中“打破”字符串头或其他文件(例如重命名或添加废话),看看它是否会影响另一个?
标签: c++ gcc c++11 centos centos6.5