内联私有成员函数的符号发射

问题描述

假设下面的虚拟标头-源对如预期那样被编译为一个转换单元。

struct foo {
  public:
    int bar(int x);
  private:
    int baz();
};
int foo::bar(int x) {
    return baz() * 2 - 1;
}
int foo::baz() {
    return 42;
}

到目前为止,在我使用过的每个编译器中,foo::baz()都很短,因此可以内联到foo::bar(int)中。但是,尽管实际上实际上永远无法从类外部访问它,但它们中的每一个仍然会发出该函数的离线副本(除非原始符号被直接引用或以其他方式引用,如C ++成员可见性!=符号)。能见度)。即使使用-fvisibility=hidden(在支持此标志的编译器上),也会发生这种情况。

这是为什么我经常喜欢启用LTO的部分原因,因为它具有很好的副作用,即当它们被内联并且从未被引用为符号时,它会自动装扮(或首先不发出)这样的功能(因为就会知道,永远不会发出在链接的二进制文件中从未引用过的隐藏符号)。启用这两项功能后,foo::baz()不会发出,这正是我想要的。但是,出于某种原因,我不能在每个项目中启用LTO。因此,我的问题是如何鼓励编译器在没有LTO之类的帮助下不发出这些函数。

对于上下文,我主要对CCC和类似GCC的编译器(例如Clang和MinGW)感兴趣,但是如果有一种独立于编译器的方式,那就更好了。

说到这一点,可以使用静态的非成员函数,如果内联了该函数,它将不会被离线发出,这样就永远不会引用离线副本,但这似乎由于显而易见的原因(例如,访问私人成员会比较麻烦),这是一种相当笨拙的方式来解决此问题。此外,并非总是我的代码被编译,因此在编译其他人的代码时,我也想减轻这个问题。

通常,这并不是什么大问题,因为当这些函数以离线方式发出时,它们可能足够小或微不足道,因此它们首先会被内联,因此可能不是二进制文件中的所有空间都非常浪费。不过,确实感觉有些多余,可能需要一些调整。

有关示例源代码,请参见here

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)