c++ - 为什么在 CentOS 7 上选择了错误的 GCC 7.2 libstdc++ ABI?

标签 c++ c++11 gcc centos c++14

我正在尝试在 CentOS 7 上使用 GCC 7.2.1 编译一个简单的程序。在找到 this package 之后,我在新的 Docker CentOS 镜像上使用以下命令安装了 g++:

$ yum install centos-release-scl-rh
$ yum install devtoolset-7-gcc-c++
$ ln -s /opt/rh/devtoolset-7/root/usr/bin/g++ /usr/local/bin/g++

确认安装:

$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-7/root/usr --mandir=/opt/rh/devtoolset-7/root/usr/share/man --infodir=/opt/rh/devtoolset-7/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --enable-plugin --with-linker-hash-style=gnu --enable-initfini-array --with-default-libstdcxx-abi=gcc4-compatible --with-isl=/builddir/build/BUILD/gcc-7.2.1-20170829/obj-x86_64-redhat-linux/isl-install --enable-libmpx --enable-gnu-indirect-function --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 7.2.1 20170829 (Red Hat 7.2.1-1) (GCC) 

正在尝试编译程序:

// main.cpp
#include <string>
#include <iterator>
#include <algorithm>
#include <iostream>

int main()
{
    std::string foo {"hello world10m"};
    foo.erase(std::find(std::cbegin(foo), std::cend(foo), '1'), std::cend(foo));
    std::cout << foo << std::endl;
}

使用命令:

$ g++ -std=gnu++14 -o test main.cpp

给出以下编译器错误:

main.cpp: In function 'int main()':
main.cpp:9:79: error: no matching function for call to 'std::basic_string<char>::erase(__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >, std::basic_string<char>::const_iterator)'
     foo.erase(std::find(std::cbegin(foo), std::cend(foo), '1'), std::cend(foo));
                                                                               ^
In file included from /opt/rh/devtoolset-7/root/usr/include/c++/7/string:52:0,
                 from main.cpp:1:
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.h:4476:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::erase(std::basic_string<_CharT, _Traits, _Alloc>::size_type, std::basic_string<_CharT, _Traits, _Alloc>::size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::basic_string<_CharT, _Traits, _Alloc>::size_type = long unsigned int]
       erase(size_type __pos = 0, size_type __n = npos)
       ^~~~~
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.h:4476:7: note:   no known conversion for argument 1 from '__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >' to 'std::basic_string<char>::size_type {aka long unsigned int}'
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.h:4492:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::iterator std::basic_string<_CharT, _Traits, _Alloc>::erase(std::basic_string<_CharT, _Traits, _Alloc>::iterator) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::basic_string<_CharT, _Traits, _Alloc>::iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >; typename _Alloc::rebind<_CharT>::other::pointer = char*]
       erase(iterator __position)
       ^~~~~
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.h:4492:7: note:   candidate expects 1 argument, 2 provided
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.h:4512:7: note: candidate: std::basic_string<_CharT, _Traits, _Alloc>::iterator std::basic_string<_CharT, _Traits, _Alloc>::erase(std::basic_string<_CharT, _Traits, _Alloc>::iterator, std::basic_string<_CharT, _Traits, _Alloc>::iterator) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::basic_string<_CharT, _Traits, _Alloc>::iterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >; typename _Alloc::rebind<_CharT>::other::pointer = char*]
       erase(iterator __first, iterator __last);
       ^~~~~
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.h:4512:7: note:   no known conversion for argument 1 from '__gnu_cxx::__normal_iterator<const char*, std::basic_string<char> >' to 'std::basic_string<char>::iterator {aka __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >}'

据我所知,错误的libstdc++ ABI正在被选中。此示例在 Ubuntu 16 上编译良好。发生了什么?

最佳答案

如前所述here ,看起来 devtoolset-7 附带的 gcc 版本默默地忽略了 RHEL6 和 7 下的 _GLIBCXX_USE_CXX11_ABI 标志。该行为可能已转发给 centos。

关于c++ - 为什么在 CentOS 7 上选择了错误的 GCC 7.2 libstdc++ ABI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47912089/

相关文章:

c++ - 使用 boost 格式化负数

c++ - for 循环在满足条件时不会结束

c++ - 从 C++ 数组中删除元素

gcc - 动态链接 gcc

c++ - 在c++中为字符串添加标点符号

c++ - std::atomic 变量的比较操作线程安全吗?

C++动态检测参数类并将其转换为

C++ vector 旋转所有组合

gcc - '-std' 和 '--std' 编译器标志之间的差异

c++ - collect2.exe 有什么作用?