gpt4 book ai didi

c++ - 保证内联静态 Meyers 单例的对象生命周期,并明确放置在一个部分中?

转载 作者:行者123 更新时间:2023-12-05 05:46:32 25 4
gpt4 key购买 nike

我继承了一些在 g++ 9 和 10 下编译良好的代码,但是当打开优化时,两个编译器都会出现运行时错误(也就是说,编译 -O0 有效,但编译 -Og 会给出来自 MMU 的运行时错误.)

问题是在一个类的内联静态方法中定义了一个 Meyers 单例,并且该对象似乎被优化掉了。方法中的静态对象是用部分属性声明的,这很复杂(这是 g++ 语言扩展,用于将选项放置在目标文件的特定部分中。)

这里是情况的总结。

文件c.hpp


namespace my_prod {

class C {
// C has a default c'tor
public:
static C& instance() {
static C c __attribute__((section("MY_C_SECTION")));
return c;
}

void f();
};
}

文件c.cpp

#include "c.hpp"

using namespace my_prod;

void C::f() {
// implementation of f, doesn't use instance()
}

文件 p.hpp

namespace my_prod {

class P {
public:
static void g();
};
}

然后文件p.cpp

#include "p.hpp"
#include "c.hpp"

using namespace my_prod;

void P::g() {
C::instance().f();
}

链接器脚本包括:

MEMORY
{
BIG_CHUNK (rw) : ORIGIN = <address>, LENGTH = <enormous>
}

SECTIONS
{
.my_space (NOLOAD) :
{
. = ALIGN(32);
*(MY_C_SECTION)
} > BIG_CHUNK
}

对于两个优化级别,objdump -C -r -t p.o 给出

00000000  w    O MY_C_SECTION    00002220 my_prod::C::instance::c

(即,所以不是局部的,也不是全局的,但它很弱。)

但是 elf 文件上的 objdump 在优化为 -O0 时显示 BIG_CHUNK 中的符号,但在优化为 -Og 时丢失。

项目定义以下开关可能是相关的::

-ffunction-sections
-fdata-sections
-Wl,--gc-sections

尽管这些开关始终适用于所有构建。

解决方案是将 my_prod::C::instance() 方法的定义移动到 c.cpp 中。然后该符号在本地定义并且不再弱,并且无论优化级别如何都出现在最终的 Sprite 中。

我的问题是,解释这种行为的 C++ 规则是什么?

最佳答案

GCC 使用 COMDAT section groups什么时候可以实现 vague linkage .尽管被显式命名为 MY_C_SECTION,编译器仍然发出一个以 _ZZN7my_prod1C8instanceEvE1c 作为关键符号的 COMDAT 组:

    .section    MY_C_SECTION,"awG",@progbits,_ZZN7my_prod1C8instanceEvE1c,comdat

我希望您对 MY_C_SECTION 的其他使用属于具有相同签名符号的 COMDAT 组。这会导致链接编辑器对节垃圾收集产生歧义。

如果不进行优化,编译器会发出对 _ZZN7my_prod1C8instanceEvE1c 签名符号的引用,而碰巧在链接器垃圾回收的这个特定实现中,这足以保留 MY_C_SECTION 目标文件中的部分和 _ZZN7my_prod1C8instanceEvE1c 符号定义。通过优化,该引用消失了,并且由于情况不明确,链接编辑器丢弃了定义。

没有 my_prod::C::instance() 的内联定义,就没有模糊的链接和涉及的 COMDAT 组,因此不会出现歧义,链接描述文件按预期工作。

要在保留内联定义的同时解决这个问题,使用唯一的节名称代替 MY_C_SECTION 并在链接描述文件中引用它可能就足够了。

关于c++ - 保证内联静态 Meyers 单例的对象生命周期,并明确放置在一个部分中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71159998/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com