如何在Linux/gcc上创建与pthreads和libstdc ++静态链接的共享对象?
我做了一些谷歌,似乎无法为此发现GCC选项或libstdc ++宏.是否可以在所有std::atomic模板特化上强制使用内部锁定.在某些平台上,一些专业化无论如何都是锁定的,因此它看起来似乎是一个可行的选择.
在过去,我发现在使用Valgrind(Helgrind或DRD)std::atomic等工具调试数据竞争时,由于大量的误报,使用起来非常痛苦.如果使用atomics足够普遍,抑制文件似乎不是一个非常可扩展的解决方案.
以下程序演示了libc ++和libstdc ++之间std :: getline行为的不一致性(使用clang3.3).
程序打开文件testfile,读取它直到eof,然后使用ifstream :: clear清除错误位并再次尝试从同一个文件句柄读取以查看是否有新数据附加到文件中.
#include <fstream>
#include <iostream>
#include <unistd.h>
using namespace std;
int main() {
ifstream* file = new ifstream("testfile");
if ( ! file->is_open() ) {
cout << "testfile does not exist" << endl;
return -1;
}
while ( 1 ) {
file->clear(); // remove end of file evil bits
string line;
// workaround:
// file->seekg(file->tellg());
while ( getline(*file, line) )
cout << "read line: " << line << endl;
if ( file->eof() )
cout …Run Code Online (Sandbox Code Playgroud) 我一直在尝试从使用的源代码编译gcc 4.x --with-fpmath=387但是我收到了这个错误:"Invalid --with-fpmath=387".我查看了配置并发现它不支持此选项(即使文档仍然提到它作为可能的选项):
case ${with_fpmath} in
avx)
tm_file="${tm_file} i386/avxmath.h"
;;
sse)
tm_file="${tm_file} i386/ssemath.h"
;;
*)
echo "Invalid --with-fpmath=$with_fpmath" 1>&2
exit 1
Run Code Online (Sandbox Code Playgroud)
基本上,我开始了这一切,因为我需要为旧的目标平台提供可执行文件(事实上,它是一个旧的Celeron,但没有任何SSE2指令显然由libfdc ++由DEFAULT使用).可执行文件在第一条指令(movq XMM0,...)崩溃,该指令来自libstdc ++中的复制例程,带有"非法指令"消息.有什么方法可以解决这个问题吗?我需要使用相当新的g ++才能移植现有的代码库.
我想知道是否可以从旧版本提供这些头文件/源代码以支持常规x87指令,以便不引用SSE指令?
更新:请注意我在谈论编译的libstdc ++在目标代码中有SSE2指令,所以问题不在于gcc命令行参数.无论我在编译代码时向gcc提供什么,它都将与已经内置SSE2指令的libstdc ++链接.
真正的答案是在编译GCC时不使用任何 --with-fpmath开关.我对配置脚本switch语句感到困惑,认为它只支持sse或avx,而实际上是默认值(此开关中未提及的是"387").因此,请确保在运行configure时不使用--with-fpmath.我没有它重新编译GCC,它现在工作正常.
谢谢.
我的应用程序引入了许多共享库.有些是用C++编写的,它引入了libstdc ++.所以它引入了libgcc_s.so.还有一些是用简单的C编写的,并与-static-libgcc相关联.
所以现在我在多个共享库中静态链接了一些libgcc,并且libstdc ++在运行时动态加载libgcc的其他位.
Q1:这个设置会给我带来麻烦吗?libgcc是否具有会使这种混合链接出现问题的内部状态,还是只是内联函数?
Q2:为了让我的应用程序适用于较旧的Linux,我应该发布libstdc ++.so和libgcc_s.so并在主exe上使用rpath来加载它.这是正确的方法吗?
以下程序无法与clang和-stdlib = libstdc ++链接:
$ cat future.cpp
#include <iostream>
#include <future>
int main()
{
std::future<int> f1 = std::async([](){ return 42; });
f1.wait();
std::cout << "Magic number is: " << f1.get() << std::endl;
}
$ g++-mp-5 future.cpp -std=c++11 && ./a.out
Magic number is: 42
$ clang++-mp=3.5 future.cpp -std=c++11 && ./a.out
Magic number is: 42
Run Code Online (Sandbox Code Playgroud)
使用clang和-stdlib = libstdc ++构建时,会发生以下链接错误:
$ clang++-mp-3.5 future.cpp -std=c++11 -stdlib=libstdc++ -I/opt/local/include/gcc5/c++ -I/opt/local/include/gcc5/c++/x86_64-apple-darwin14 -L/opt/local/lib/gcc5 -lstdc++ && ./a.out
Undefined symbols for architecture x86_64:
"std::__once_call", referenced from:
void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用std::literals名称空间中的文字来编译一个简单的程序,但是当我尝试对其进行编译时,Clang会生成错误。
我正在尝试编译的代码:
#include <string>
#include <iostream>
using namespace std::literals;
int main()
{
std::cout << "Hello World!"s << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
和编译命令:
clang++ -stdlib=libstdc++ -std=c++1y a.cpp
Run Code Online (Sandbox Code Playgroud)
导致此输出:
a.cpp:4:22: error: expected namespace name
using namespace std::literals;
~~~~~^
a.cpp:8:29: error: no matching literal operator for call to 'operator "" s' with arguments of
types 'const char *' and 'unsigned long', and no matching literal operator template
std::cout << "Hello World!"s << std::endl;
^
2 errors generated.
Run Code Online (Sandbox Code Playgroud)
由于各种原因,无法使用g ++或libc ++,并且我已经确认其他C ++ …
根据标准,std::vector<bool>没有会员功能data().但是,以下代码段与使用libstdc ++的最新GCC编译良好:
#include <vector>
int main () {
std::vector<bool> v;
v.data();
}
Run Code Online (Sandbox Code Playgroud)
如果我们尝试使用结果,则返回类型为void.
这是一些gcc扩展还是一个bug?
如果前者是真的,它会做什么?
是的,这可能是你第三次看到这段代码,因为我问了另外两个关于它的问题(这个和这个)..代码很简单:
#include <vector>
int main() {
std::vector<int> v;
}
Run Code Online (Sandbox Code Playgroud)
然后我在Linux上使用Valgrind构建并运行它:
g++ test.cc && valgrind ./a.out
==8511== Memcheck, a memory error detector
...
==8511== HEAP SUMMARY:
==8511== in use at exit: 72,704 bytes in 1 blocks
==8511== total heap usage: 1 allocs, 0 frees, 72,704 bytes allocated
==8511==
==8511== LEAK SUMMARY:
==8511== definitely lost: 0 bytes in 0 blocks
==8511== indirectly lost: 0 bytes in 0 blocks
==8511== possibly lost: 0 bytes in 0 blocks
==8511== still …Run Code Online (Sandbox Code Playgroud) 使用该函数libc++版本的程序getline在从管道读取输入时将阻塞,直到管道缓冲区已满。
对于该函数的版本,情况并非如此:在此处,该函数将立即读取并在输入可用后立即返回一行输入。libstdc++getline
我应该期待libstdc++和之间的这种行为差异libc++吗?[ 编辑:我在这里不是要征求意见,我只是对管道不甚了解,也对实施C ++标准库的困难不甚了解。对我来说,这种行为差异肯定是令人惊讶的,但也许有人知道更好,可以向我保证这种差异是可以预料的,也许这只是一个实现细节?]
更重要的是,我该怎么做才能libc++像人一样libstdc++?也就是说,该getline函数不应等到管道缓冲区已满,而应在可用时立即返回一行输入。
参见下面的代码示例,该代码示例显示了如何读取和写入管道。
我怀疑问题不仅限于macOS,但我还没有clang可以用来测试的Linux开发系统。
打开三个壳,我们称它们为A,B和C。
在外壳A中:创建一个新文件pipe-test.cpp并从下面添加源代码。一次编译源代码,一次编译libstdc++一次libc++:
g++ -stdlib=libstdc++ -o pipe-test-libstdc++ pipe-test.cpp
g++ -stdlib=libc++ -o pipe-test-libc++ pipe-test.cpp
Run Code Online (Sandbox Code Playgroud)
在外壳A中:创建两个管道:
mkfifo input-pipe output-pipe
Run Code Online (Sandbox Code Playgroud)
libstdc++程序版本pipe-test-libstdc++ input-pipe output-pipecat output-pipecat >input-pipe