我有一个链接错误,我认为我不应该有:
koala.o:
In function `ns1::utils::io::protocol::InputSequenceFile
<
ns1::utils::io::protocol::TargetSequenceProtocol<
ns1::utils::io::FooIndexTarget
>
, false
>::InputSequenceFile(ns1::utils::io::DataFileDescriptor const&) [clone .constprop.1291]':
koala.cpp:(.text+0x332a):
undefined reference to
`ns1::utils::io::DataFileFactory::createIndexedInputFile
(
ns1::utils::io::DataFileDescriptor const&, ns1::utils::io::IndexMode::Enum, bool
)'
Run Code Online (Sandbox Code Playgroud)
(我只更改了空格,以便更容易阅读。我还非常小心地做了一些匿名化。)
然后我曾经nm发现有关符号的情况:
nm other.o:
0000000000008f20 t _ZN4ns15utils2io15DataFileFactory22createIndexedInputFileERKNS1_18DataFileDescriptorENS1_9IndexMode4EnumEb.constprop.1677
nm koala.o:
U _ZN4ns15utils2io15DataFileFactory22createIndexedInputFileERKNS1_18DataFileDescriptorENS1_9IndexMode4EnumEb
Run Code Online (Sandbox Code Playgroud)
(grepped 输出)
它们是相同的,不计算constprop.1677(我不知道它是什么)。所讨论的方法是类的静态方法。我需要一些帮助来了解问题的根本原因。
-O3gcc的开关-fipa-cp-clone默认打开,添加-fno-ipa-cp-clone到命令行以禁用。
该开关在编译器中启用控制和到达流分析中的相关优化,该编译器引入了可以显示为常量值的函数的折叠克隆版本,并且在编译对象中,这些克隆可以通过.constprop后缀标识。
背景
恒定传播是众所周知的全局流分析问题。常量传播的目标是发现在程序的所有可能执行中都是常量的值,并在程序中尽可能远地传播这些常量值。操作数都是常量的表达式可以在编译时计算,结果可以进一步传播。
韦格曼,马克 N;Zadeck, F. Kenneth(1991 年 4 月),“Constant Propagation with Conditional Branches”,ACM Transactions on Programming Languages and Systems 13 (2): 181–210
这是一个具体的例子:
int foo (int x, int y) {
if (y == 0) return 0;
return foo (x, --y) % 2;
}
int main () {
int z = 0;
for (int i = 0; i < 6; i++) {
z = z + foo (1, i);
}
}
// g++-4.8 -c -O2 -fipa-cp-clone main.cpp && nm main.o
0000000000000030 T _Z3fooii
0000000000000000 t _Z3fooii.constprop.0
0000000000000000 T main
Run Code Online (Sandbox Code Playgroud)
您可以观察到,-fipa-cp-clone编译器识别出有一个常量被传递给外部可见的foo()方法,并通过克隆函数为优化做准备。
(见现场直播)