【问题标题】:GCC 4.4 fails to link valid C++11 code, when options are -std=C++0x -O0GCC 4.4 fails to link valid C++11 code, when options are -std=C++0x -O0
【发布时间】:2013-12-19 15:45:39
【问题描述】:

这是一个基于第一个答案的编辑问题。其他人向我指出,我认为无效的代码在 C++11 中完全没问题。尽管如此,gcc 的行为会有所不同,具体取决于不应相关的内容。


有一个文件,包含

std::string logFilePath;
/*...*/
std::ofstream logfile(logFilePath, std::ofstream::trunc);

此行在 Windows (MSVC2010) 和 linux (G++4.4) 下使用 -std=c++0x 设置编译和链接。当我给出-O0 选项时,链接中断并给出错误:

 undefined reference to `std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::_Ios_Openmode)'

问题是为什么会发生这种情况?这似乎是gcc 中的一个错误,但任何进一步的信息都会很棒。

有一个老的thread 涉及同样的问题,这导致我-Ox 是罪魁祸首,但没有解释,只有解决方案提示。


这是一个最小的例子:

#include <string>
#include <fstream>
#include <iostream>

int main (int, char**)
{
    std::string name = "name";
    std::ofstream stream(name, std::ofstream::trunc);
    return 0;
}

然后:

$ /usr/bin/g++44 -std=c++0x main.cpp -Wall -O1
$ /usr/bin/g++44 -std=c++0x main.cpp -Wall -O0
    /tmp/ccBjIuWi.o: In function `main':
    main.cpp:(.text+0x80): undefined reference to `std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::_Ios_Openmode)'
    collect2: ld returned 1 exit status

第一行编译良好,并给出了不考虑优化级别集的预期行为,-O0 除外,即123s 中的任何一个都可以。


以下是有关系统的一些附加信息:

$ /usr/bin/g++44 -v
    Using built-in specs.
    Target: x86_64-redhat-linux6E
    Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --disable-gnu-unique-object --with-as=/usr/libexec/binutils220/as --enable-languages=c,c++,fortran --disable-libgcj --with-mpfr=/builddir/build/BUILD/gcc-4.4.7-20120601/obj-x86_64-redhat-linux6E/mpfr-install/ --with-ppl=/builddir/build/BUILD/gcc-4.4.7-20120601/obj-x86_64-redhat-linux6E/ppl-install --with-cloog=/builddir/build/BUILD/gcc-4.4.7-20120601/obj-x86_64-redhat-linux6E/cloog-install --with-tune=generic --with-arch_32=i586 --build=x86_64-redhat-linux6E
    Thread model: posix
    gcc version 4.4.7 20120313 (Red Hat 4.4.7-1) (GCC)
$ cat /etc/redhat-release
    CentOS release 5.9 (Final)

【问题讨论】:

  • gcc 4.4 是古老的,它的 c++0x 模式肯定在许多层面上都被破坏/不完整。
  • @PlasmaHH,很遗憾,我无法切换 gcc 版本

标签: c++ linux c++11 g++


【解决方案1】:

在 C++ 标准 2011 中添加了带有 std::basic_string 的构造函数。在此之前,此构造函数不存在。取而代之的是参数类型为 const char * 的构造函数。

【讨论】:

    【解决方案2】:

    那是因为代码在 C++11 中不是无效的。 A constructor taking an std::string as first argument 添加了 C++11。标志 std=c++0x 告诉 g++ 在 C++11 模式下编译(或它在您的版本中支持的未来 C++11 的任何子集)

    在 C++03 中,你需要传递一个const char*:

    std::ofstream stream(name.c_str(), std::ofstream::trunc);
    

    至于对优化级别的依赖,这很可能是您的安装问题,或者该特定版本的 g++ 中的真正错误。不幸的是,我无法复制它。

    【讨论】:

    • 虽然您的答案似乎与@Vlad 相同,但您至少指出优化依赖似乎是错误。好像是这样,我不知道std::string-taking 构造函数被添加,现在这似乎不那么神秘了。
    • @idji 在我的回答中隐含的是,在较新版本的 g++ 中也没有出现问题。但是,如果您添加了确切的版本(4.4.x 中的 x),并且如果可能的话,添加操作系统会有所帮助。稍后我可能会检查一些 RH gcc 4.4 框。
    • 我已编辑问题以(希望)回答您关于版本和其他内容的问题。
    猜你喜欢
    • 1970-01-01
    • 2013-10-31
    • 2013-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多