2009-01-10 98 views
1

任何人都有一个链接到C++标准说关于编译器移除全局和静态符号是什么?我认为你不能保证编译器会删除全局符号,如果它们没有被引用。我的一位同事断言,如果您的全局符号包含在主翻译单元中,即使这些符号未被引用,这些符号也不会被删除。C++标准和全局符号去除

回答

3

有趣的是,所有我可以找到关于此在C++ 2003标准是这样的:

3.7.1静态存储持续时间[basic.stc.static]

所有既不具有对象动态 存储时间也不是本地有 静态存储时间。这些对象的存储 应持续计划(3.6.2,3.6.3 )的 时间。

如果静态存储的目的 持续时间具有初始化或 析构函数副作用,应当 不即使它出现 是未使用的,不同的是一类 对象或它的拷贝可以被消除 消除详见 12.8。

这意味着该标准允许在静态存储中删除项目,如果它们的初始化和销毁​​没有副作用并且它们未被使用。

如果有一个更直接的权限,我没有看到它(但也许别人会)。

但是,应该指出的是,具有连接消除了最终图像中未使用的对象是一个很常见的优化。

0

你在问关于链接的问题,虽然C++标准说链接应该作为翻译的最后阶段发生,但它没有提到怎么样应该发生。例如,它表示函数引用已解析,但不要求它们按名称解析,也不会说明解析后引用会发生什么。

可以确定编译器包括目标代码,以及哪些链接或不删除,你需要查阅文档编译器和链接,分别您使用的是什么符号。

+0

在C++标准范围内链接_is_。这是汇编的最后阶段之一,其中翻译单位合并。不过,措辞有所不同。类似于byte!= octet – MSalters 2009-01-12 10:32:50

0

这是这样,我相信(我们在评论线程在此早些时候堆栈溢出了长时间的讨论):

  1. 如果初始化或析构函数对象与命名空间范围(即与对象静态存储持续时间)没有副作用,如果在其翻译单元中没有使用函数或对象,则可以优化对象。
  2. 对于对象其初始化或破坏引起的副作用,则编译器可能不优化该变量时,即使没有使用其翻译单元的对象或功能。

在任何情况下,编译器必须在使用完成之前初始化对象,但不一定在main之前。我做了测试,因为有人在stackoverflow表示,如果没有这样的用途,gcc会有效地优化对具有副作用的对象的初始化。我现在测试过了,我已经看到gcc没有这样做。此外,据我了解标准,它不允许这样做。

如果您只是取得您想要初始化的对象的翻译单元的对象或函数的地址就足够了。为了安全起见,最好总是这样做,即使对于有副作用的初始化对象。假设你的朋友是对的,我认为主要的翻译单元,main总是被看作为使用,所以立即满足条件。规则可以在3.6.2p3,3.7.1p23.2p2(定义使用),1.9p7(定义副作用)中找到。