以下代码(作为大型项目的一部分进行编译)不会打印数字(不仅是one-byte integers,而且还包括以下任何一个:std::int32_t
,std::size_t
,double
等)。当然,此代码本身可以完美地编译,因此不可能提供一个最小的示例来重现此问题:这个大项目中的某件事导致了它的发生,但我无法完全理解导致它的原因。 -因此是这个问题。
代码:
std::int32_t n = 42;
std::cout << "test 1" << std::endl; // prints
std::cout << 3.14 << std::endl; // doesn't print
std::cout << 456464 << std::endl; // doesn't print
std::cout << n << std::endl; // doesn't print
std::cout << "test 2" << std::endl; // still doesn't print
printf("printf: %d\n", n); // prints
std::cout.clear();
std::cout << "test 3" << std::endl; // prints
std::cout << 42 << std::endl; // doesn't print
输出:
test 1
printf: 1
test 3
因此,数字文字3.14
和456464
以及变量n
的输出不如字符串test 2
(我在整数打印失败后尝试打印字符串) )。 printf
函数起作用。我使用std::endl
,所以它应该不是任何缓冲问题。
使用std::cout.clear()
似乎可以解决问题(我们可以再次打印字符串),但是只能等到另一个数字被打印出来。
对输出流进行哪种操作可能会导致这种情况?是的,有using namespace std;
。
使用GCC工具链用-std=c++11
编译代码(我尝试了5.3.1、6.3.1和8.2.0的各种版本-结果始终相同)。
编译命令行:
g++ c -MMD -pipe -std=c++11 -fPIC -O3 \\
-fmax-errors=3 -msse4.1 -mavx2 source.cpp -o target/objects/source.o
链接命令行:
g++ <object files> -o executable -s \\
-Wl,--build-id=uuid -static-libstdc++ -pthread -Wl,--no-undefined
答案 0 :(得分:0)
经过一些调试后,我设法找到了罪魁祸首。这不是一个完整的答案,因为它不能解释观察到的症状(不是特别打印数字,以及为什么使用std::cout.clear()
至少可以部分解决问题),但是此答案将提供一个最小的示例,可以用来重现问题。希望它将为某人节省一些时间。
出现异常行为的原因是内存使用问题,即线程本地存储(TLS)用完了。可以通过涉及大量使用TLS的任何方式来重现该问题。下面的示例使用OpenCV并为此静态链接到libstdc++
。为了加快速度,我们将使用Python避免编写过多的代码。
C ++部分:
#include <iostream>
#pragma GCC visibility push(default)
extern "C" void fun() {
std::cout << "hello 0" << std::endl;
std::cout << 42 << std::endl;
std::cout << "hello 2" << std::endl;
}
#pragma GCC visibility pop
编译并与之链接(-static-libstdc++
在此很重要,因为该库因大量使用TLS而闻名)
g++ -std=c++11 -fPIC test.cpp -s -static-libstdc++ -pthread -shared -o libtest.so
现在使用Python和ctypes
模块加载我们的库:
import numpy as np
lib = np.ctypeslib.load_library('libtest', '.')
lib.fun()
如果这样运行,它将打印(按预期):
hello 0
42
hello 1
现在让我们添加另一个大量使用TLS的库:
import numpy as np
import cv2 # <-----
lib = np.ctypeslib.load_library('libtest', '.')
lib.fun()
这将打印:
hello 0
请注意,特定的可重复性可能取决于您操作系统的TLS限制设置。