Pyp*_*ros 1 c++ devkitpro ld thread-safety suppress-warnings
我有一些使用本地范围、程序生命周期对象的 C++ 代码,例如
void testFunction(int arg) {
static Tested tested(0);
tested.use(arg);
}
Run Code Online (Sandbox Code Playgroud)
它与旧版本的 GCC 构建得很好。使用 GCC 8.2.0,我在链接时收到令人费解的警告:
警告:使用旧版兼容的 __sync_synchronize。不适合多线程应用
它指向定义测试的行,并且确实存在对编译器生成的 __sync_synchronize() 的调用。我想它是为了确保没有两个线程可以同时运行初始化代码,并使延迟初始化产生与加载时初始化相同的结果。
Tested 类的此实现重现了问题:
class Tested {
int sum;
public:
Tested(int init) : sum(init) {}
void use(int arg) {
sum += arg;
}
int current() const {
return sum;
}
};
Run Code Online (Sandbox Code Playgroud)
该代码预计在单线程嵌入式平台上运行。
我是否正确地认为该警告与我无关?
我可以做什么(除了停止使用静态对象)来消除警告消息?
您将收到由该版本的 newlib 生成的链接器警告,告诉您您的应用程序已调用__sync_synchronize并且没有实际同步的该函数的实现。newlib 中该函数的实现是一个不执行任何操作的存根(它的存在可能只是为了确保不存在对该函数的未定义引用)。
这些调用可能来自内部libstdc++.so,因为 ARM 上的 GCC 会发出对__sync_synchronize库内部发生的某些原子操作的调用(例如,std::string或shared_ptr对象中的引用计数更新)。
__sync_synchronize要获得使原子正确的工作,您可能需要链接到libatomic(使用-latomic),它将具有该函数的实现。因为您没有链接到它,所以您在 newlib 中获得了后备存根实现。如果您不需要同步原子(因为您的应用程序是单线程的,并且从不尝试更新信号处理程序中的原子),那么我认为您可以忽略该警告。
另一种选择是使用 libstdc++.so 的构建,它显式禁用所有线程,理论上不会有任何对__sync_synchronize. 但 libstdc++.so 的构建只能用于单线程应用程序。您现在使用的构建可用于单线程和多线程代码(即使您收到与单线程情况不太相关的警告)。