众所周知,glibc(以及据我所知,glibstd ++)也使用符号版本控制机制.(有关详细信息,请参阅: 如何链接到特定的glibc版本.)
问题是如何确定GLIBC和GLIBCXX的确切版本将由链接器为libc和libstdc ++中的名称选择?例如,如何得到这样的东西:
time -> time@GLIBC_2_5
...
gethostbyname -> gethostbyname@GLIBC_2_3
Run Code Online (Sandbox Code Playgroud)
我们为什么需要这个?在我看来,如果你想最小化所需的glibc/libstdc ++版本,它会很有用.
当我使用g ++在我的计算机上编译一个c ++程序并传输可执行文件以在我的大学服务器上运行它时,我得到了
./main: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./main)
./main: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by ./main)
./main: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by ./main)
Run Code Online (Sandbox Code Playgroud)
该程序在我的计算机上运行良好,我没有权限在我的大学服务器上安装任何新软件.
任何帮助?谢谢
我正在尝试加载使用SWIG创建的PHP扩展,但是在启动PHP时出现以下错误:
PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php5/20090626/libtg.so' - /usr/lib/php5/20090626/libtg.so: undefined symbol: __gxx_personality_v0 in Unknown on line 0
Run Code Online (Sandbox Code Playgroud)
我试图加载的扩展名是命名的libtg.so,并使用以下命令编译:
g++ -shared libtg_wrap.o -o libtg.so
Run Code Online (Sandbox Code Playgroud)
其中libtg_wrap.o是SWIG生成的包装器代码的目标文件.
__gxx_personality_v0可以找到缺少的符号libstdc++.so,如以下命令所示:
$ nm -D /usr/lib/libstdc++.so.6 | grep __gxx_personality_v0
00000000000b9990 T __gxx_personality_v0
Run Code Online (Sandbox Code Playgroud)
libstdc++.solibtg.so在以下命令中可以参考:
$ ldd libtg.so
linux-vdso.so.1 => (0x00007fff5f932000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f3fc937c000)
libm.so.6 => /lib/libm.so.6 (0x00007f3fc90f9000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f3fc8ee2000)
libc.so.6 => /lib/libc.so.6 (0x00007f3fc8b5f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3fc98fc000)
Run Code Online (Sandbox Code Playgroud)
所以我不明白为什么它找不到符号.关于如何进一步调试这个的任何想法?
与CodeReview 上的这个问题相关,我尝试使用std::unordered_map自定义分配器,但显然这不适用于gcc/clang和libstdc ++.可以通过使用a初始化空哈希映射来生成错误std::allocator
#include <unordered_map>
int main()
{
typedef std::allocator<std::pair<const int, int>> A;
typedef std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, A> H;
auto h = H{A()}; // ERROR, cannot find constructor H::H(const A&)
}
Run Code Online (Sandbox Code Playgroud)
实例.
问题:libstdc ++是否支持std::unordered_map使用单个分配器构造作为参数不完整?
更新:进一步检查表明,对于除了以外的几乎所有容器std::vector,libstdc ++中的分配器的使用直接访问typedef和分配器的成员函数,而不是通过std::allocator_traits.这适用于std::allocator所有自定义分配器但是失败,除非它们直接添加这些成员和typedef.
我最近了解到,自几年以来,libstdc ++库包含vstring(也称为versa_string),它提供了相同的功能std::string,但显然更符合C++标准.我曾试图用它vstring作为替代品std::string,但我发现没有简单的方法可以做到.
有没有一种简单的方法来代替std::string用vstring,在不改变的libstdc ++源代码?
我可以用std::string别名替换代码中的所有用法,如下面的清单所示.然而,这种方法的问题在于,它std::string也在某些地方内部使用,例如在std::ostringstream.这意味着,这些陈述std::ostringstream os; my::string s = os.str();不再适用.
namespace my {
#ifdef __GLIBCXX__
using string = __gnu_cxx::__vstring;
#else
using string = std::string;
#endif
}
Run Code Online (Sandbox Code Playgroud) 我想在我的应用程序中使用gcc 4.8.1(需要libstdc ++.so.6.0.18),但是客户只有libstdc ++.so.6.0.13.我已经使用-static-libgcc -static-stdlibc++了一段时间,但我的应用程序包含几个动态链接库和一个主要应用程序.这意味着在编译每个动态库时,它们必须静态编译标准库,这是多余且浪费的.我想用我的产品运送我选择的标准库,但是每次我在像他们这样的环境中运行我的应用程序时,它总是加载错误的标准库./usr/lib64/无论我似乎做什么,它都喜欢这个版本(似乎优先考虑LD_LIBRARY_PATH).
约束:
我不允许强迫他们升级到新的标准库.
我不想让动态库保持静态.(我可以将所有内容静态编译到主应用程序中一次,但是有一些后勤障碍阻止我将某些库重新编译为静态库).
-Wl,-rpath=$(path_to_directory)有点危险,但它是合法的,因为客户确实采取了一些允许我设置路径变量的设置.但是,设置我的新stdlibc ++的rpath似乎并没有覆盖默认/usr/lib64版本.我仍然会收到GLIBCXX错误,因为它不会使用正确的库.
当然有一个优雅的解决方案吗?
也许我的程序中只有一个错误.这是一个例子(对于审查员抱歉,但它只是用户名的东西):
~/example$ pwd
/home/username/example
~/example$ echo $LD_LIBRARY_PATH
~/example$ ls
Makefile libstdc++.so.6.0.18 test.cpp
~/example$ make
g++ -std=c++11 -Wall -Werror test.cpp -o test
~/example$ ldd test
./test: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by ./test)
linux-vdso.so.1 => (0x00007fffe5919000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x000000390b800000)
libm.so.6 => /lib64/libm.so.6 (0x0000003904800000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x000000390b400000)
libc.so.6 => /lib64/libc.so.6 (0x0000003904400000)
/lib64/ld-linux-x86-64.so.2 (0x0000003904000000)
~/example$ setenv LD_LIBRARY_PATH /home/username/example …Run Code Online (Sandbox Code Playgroud) 根据http://flamingdangerzone.com/cxx11/2012/07/06/optimal-tuple-i.html,关于std :: tuple ...
libstdc ++总是以相反的顺序放置成员,而libc ++总是按给定的顺序放置成员
假设这是真的,有没有理由(历史或其他)为什么libstdc ++使用逆序?
额外奖励:是否有任何实现因任何原因改变了其std :: tuple排序?
看看C++编译器支持,似乎std::shared_mutexGCC 5.0+中提供了不定时版本.但是,即使使用gcc version 5.3.0 20151204 (Ubuntu 5.3.0-3ubuntu1~14.04)和编译-std=c++1z,共享互斥锁的简单初始化最终会:
error: ‘shared_mutex’ in namespace ‘std’ does not name a type
std::shared_mutex mutex_;
Run Code Online (Sandbox Code Playgroud)
不,我已经包含了正确的标题:#include <shared_mutex>.
它找不到合适的标题,因为它似乎不存在.实际上,链接器使用的是locate at /usr/include/c++/5/shared_mutex,它只包含了实现std::shared_timed_mutex(如C++ 14标准).
我已经安装了gcc-5和g ++ - 5,通过添加存储库ppa:ubuntu-toolchain-r/test并使用它update-alternatives来正确设置它们的垃圾箱.
有没有什么可以使用最新的C++ 17标准正确编译我的代码?并且可能是一个要提出的愚蠢问题,但是-std=c++1z即使应该已经支持它,现在开始使用还为时过早吗?因为它受到支持,对吗?
继承enable_shared_from_this只是为了能够shared_ptr从成员函数返回作为主要意图,而无意enable_shared_from_this在派生类中公开API.
因为要使用enable_shared_from_this一个必须通过公共继承这样做(标准是否要求这个?基本原理是什么?),这是无法实现的,并且enable_shared_from_thisAPI被强制导入到派生类的公共API中.
Inherenting enable_shared_from_this私下和制作shared_ptr的朋友千万级铛上加上的libc ++工作,但不与stdlibc ++工作.
由于private enable_shared_from_this+ friend shared_ptr(或受保护的继承)似乎涵盖了这个用例,因此适合作为"从此共享"问题的解决方案的标准不应该足够吗?
看看这个:
#include <iostream>
#include <memory>
using Foo = int;
using FooPtr = std::shared_ptr<Foo>;
FooPtr makeFoo()
{
FooPtr f{
new Foo(),
[](Foo* ptr) {
delete ptr;
std::cerr << "!\n";
}
};
return f;
}
void bar(FooPtr p = {})
{
p = makeFoo();
}
int main()
{
bar();
}
// Expected output: '!'
// Failure case: no output (deleter not invoked?)
Run Code Online (Sandbox Code Playgroud)
我希望shared_ptr在bar()返回时调用删除器,在使用GCC 4.8.5的64位CentOS 7系统上调用它.
然而,在我的32位的CentOS下devtoolset 2中使用GCC 4.8.2 6系统(我也想下gcc-linaro-arm-linux-gnueabihf-4.8-2013.10_linux,我的树莓派工具链),它没有.
看一下代码,并给出了4.8中C++ 11的实验性质,这对我来说就像一个编译器错误.但我也可能陷入某个地方的UB陷阱(或者只是误解了这些东西应该如何工作).
谁有过错?我该如何解决?
Using …Run Code Online (Sandbox Code Playgroud)