我正在使用一个非常特殊的工具链(Analog Devices 的 SHARC DSP 处理器),我想更好地了解我的编译器/链接器。
我在某个地方有一个 volatile 全局变量:
volatile long foo;
这个变量在我的代码中没有被使用和引用,但我想在我的最终可执行文件中保留它(不要问我为什么,可悲的事实是可悲的)。
我通常使用 -e
选项链接我的项目。它告诉链接器从可执行文件中删除死代码。我最初认为没有编译器敢于删除任何全局变量,尤其是当这些符号被声明为 volatile 时。不幸的是它确实如此。
然后我发现了一个非常具体的 pragma #pragma retain_name
,它告诉链接器保留一个符号,即使它从未被使用过。
我想知道在某些 ISO/POSIX 标准中是否可以找到这种情况。我一直认为编译器或链接器都不会对可变符号做出任何假设。因此,没有编译器会尝试从最终的可执行文件中删除无效的 volatile 变量或函数。
我错了吗?
最佳答案
您可以创建一个带有使用该变量的外部链接的虚拟函数。
long
help_us_keep_foo(void)
{
return foo;
}
除非您正在执行整个程序分析,否则这将防止 foo
被删除。如果您确实执行了整个程序分析,您可以使用如下技巧。
int
main(int argc, char * * argv)
{
if (getenv("PRINT_THE_VALUE_OF_FOO_AT_PROGRAM_STARTUP"))
printf("Your hovercraft is full of eels, and foo is %ld\n", foo);
/* Do whatever your program has to do... */
return 0;
}
我一直在基准代码中使用类似的技巧(插入无害的打印语句来测试极不可能发生的情况),以确保我想要基准测试的东西没有被优化掉。
如果情况允许,您可以使用不太“可见”的技巧,例如分配 foo = foo
但由于它是 volatile
,我不确定您是否可以安全地执行此操作。
关于c - 在什么情况下 C 链接器会消除未使用的可变符号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28201618/