【问题标题】:How to find out which functions the compiler generated?如何找出编译器生成了哪些函数?
【发布时间】:2020-04-24 05:52:08
【问题描述】:

我知道编译器生成的函数、三法则和五法则。在现实世界的场景中,准确地确定哪些编译器生成的函数(构造函数、赋值运算符、析构函数)实际上是由编译器创建的,这可能并非易事。

有没有办法列出特定类的编译器生成的函数?

我主要对 Visual Studio 2019 和 Xcode 感兴趣,但更欢迎通用解决方案。

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    “有没有办法列出特定类的编译器生成的函数?”

    当然有。在 Linux(和其他 Unix 系统)上,您可以在生成的目标文件/库/可执行文件上使用 nmreadelfobjdump 来反汇编它们并检查任何导出的符号(以及更多)。

    Windows 上也有类似的工具,我知道,但这不是我经常使用的平台,所以很遗憾我无法在其中命名确切的工具名称。

    【讨论】:

    • 虽然这些工具很可能不会向您显示可能已经生成了哪些函数(即,允许编译器生成它们,但您从未使用过这些函数,所以它决定不打扰,或者链接时代码消除摆脱了它们)
    • @JMAA 在大多数情况下,“允许生成但从不使用”在标准术语中意味着一个函数是“隐式声明的”但不是“隐式定义的”。是的,这仍然意味着即使禁用了内联,您也不会看到这些符号。
    • 严格来说,这个答案确实更准确地回答了所提出的问题:“编译器生成了哪些方法?”这与不太精确的问题“编译器可能在不同的上下文中生成了哪些方法?”不同。
    • @rici 是的。但是更精确的问题不容易回答,所以我去寻找可以回答的问题。如果您认为我的回答没有价值,请随意投反对票。
    • @jesper:不,我已经投票了。正如我所说,我认为您回答的问题更准确。另一个问题,可能是意图,需要一些手,因为它是反事实的:我们不知道它可能包括什么假设的上下文。但这是字面上问的问题,有意或无意,所以回答它的荣誉。
    【解决方案2】:

    规则很复杂。我会窃取from another answer 引用Howard Hinnant's presentation 的表格。

    这里的寓意是,一个好的做法是不依赖编译器隐式声明并显式声明每个特殊成员(默认或删除,取决于您的需要)

    【讨论】:

    • 如果您明确声明每个特殊成员,您将失去移动构造函数和赋值运算符的“未声明”特殊成员状态。
    • @MaximEgorushkin 我的意思是,如果您需要它们,则将它们声明为默认(尽管默认仍可能意味着未声明),如果您不希望它们,则将其删除。
    • @bolov 该图表很有用,但这并不能回答我的问题。我想找出编译器实际生成的函数。换句话说:我不是在问理论上应该发生什么,而是在实践中发生了什么。
    • @tjwrona1992:根据这个论点,我们永远不需要测试我们的代码,因为我们知道如果编译器做了任何与我们预期不同的事情,那么其中一定有一个错误。跨度>
    • @tjwrona1992:是的,完全正确。同样,查看编译器生成的内容的目的不是验证编译器是否正确,而是验证您是否为编译器提供了正确的输入。
    【解决方案3】:

    目前这只是部分答案。

    Visual Studio 2019

    构造函数

    定义类对象时,Visual Studio 的 IntelliSense 函数会显示可用的构造函数,包括编译器生成的和您自己的:

    不幸的是,这些信息并不总是出现。为了让它适用于上面的屏幕截图,我必须在括号中输入一些内容,因此是逗号。

    【讨论】:

      猜你喜欢
      • 2020-09-26
      • 1970-01-01
      • 1970-01-01
      • 2011-08-20
      • 2020-09-02
      • 1970-01-01
      • 2023-02-06
      • 1970-01-01
      • 2016-03-14
      相关资源
      最近更新 更多