模板化函数中忽略的GCC部分属性

时间:2019-01-04 14:15:31

标签: c++ gcc attributes sections

我正在跟踪一个偷偷摸摸的错误,该错误是在我向一个类中添加模板参数时发生的。在初始化期间,它将静态局部变量放置在内存的特定部分中。

在模板化的函数/类中使用GCC的section属性似乎只是被忽略了。我的问题听起来与this user was facing类似。但是,我看不到建议的工作环境适用于我的情况。

我整理了一个非常简单的示例来说明这一点。考虑这段代码:

void handler_func() { }

using handler_type = void(*)();

struct S { handler_type handler; };

template <typename T>
void templated()
{
    static S __attribute__((section(".templ_section"))) __attribute__((used)) templ_instance {handler_func};
}

void free()
{
    static S __attribute__((section(".free_section"))) __attribute__((used)) free_instance {handler_func};
}

struct Foo{};

int main(int argc, char** argv)
{
    templated<Foo>();

    free();
}

我希望将templ_instance放在.templ_section中,并将free_instance放在.free_section中。

但是,这是GCC变量的位置:

0000000000000000 l     O .free_section  0000000000000008 _ZZ4freevE13free_instance
0000000000000000 l    d  .data.rel.local._ZZ9templatedI3FooEvvE14templ_instance 0000000000000000 .data.rel.local._ZZ9templatedI3FooEvvE14templ_instance
0000000000000000 u     O .data.rel.local._ZZ9templatedI3FooEvvE14templ_instance 0000000000000008 _ZZ9templatedI3FooEvvE14templ_instance

这是Clang所做的:

0000000000000000 l     O .free_section  0000000000000008 _ZZ4freevE13free_instance
0000000000000000  w    O .templ_section 0000000000000008 _ZZ9templatedI3FooEvvE14templ_instance

我不敢相信这是GCC中的预期行为。有什么办法解决吗?

1 个答案:

答案 0 :(得分:1)

如果碰巧templ_instance的类型不取决于模板类型T,则可以通过在自由函数中包含该对象来解决该问题:

S& templated_impl()
{
    static S __attribute__((section(".templ_section"))) __attribute__((used)) templ_instance {nullptr};
    return templ_instance;
}

template <typename T>
void templated()
{
    static S& templ_instance = templated_impl();
    templ_instance = { handler_func };
}

Live demo

GCC(8.x)

  .zero 8
  .section .free_section,"aw"
  .align 8
  .type free()::free_instance, @object
  .size free()::free_instance, 8
free()::free_instance:
  .quad handler_func()
  .section .templ_section,"aw"  // BINGO!
  .align 8
  .type templated_impl()::templ_instance, @object
  .size templated_impl()::templ_instance, 8
templated_impl()::templ_instance:

C(7.x)

  .size void templated<Foo>(), .Lfunc_end4-void templated<Foo>()
  .cfi_endproc
  .type templated_impl()::templ_instance,@object # @templated_impl()::templ_instance
  .section .templ_section,"aw",@progbits
  .p2align 3
templated_impl()::templ_instance:
  .quad handler_func()
  .size templated_impl()::templ_instance, 8

  .type free()::free_instance,@object # @free()::free_instance
  .section .free_section,"aw",@progbits
  .p2align 3
free()::free_instance: