如何找出编译器生成的函数?


11

我知道编译器生成的函数,三个规则和五个规则。在实际情况下,准确地找出编译器实际创建了哪些编译器生成的函数(构造函数,赋值运算符,析构函数)可能并不容易。

有什么方法可以列出特定类的编译器生成的函数吗?

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

Answers:


11

规则很复杂。我将从另一个答案中窃取,该答案引用了Howard Hinnant的演讲中的一张桌子。

在此处输入图片说明

这里的道理是,好的做法是不要依赖编译器的隐式声明,而不必显式声明每个特殊成员(默认还是删除,具体取决于您的需要)


如果显式声明每个特殊成员,则移动构造函数和赋值运算符将失去“未声明”特殊成员状态。
Maxim Egorushkin

@MaximEgorushkin我的观点是,如果需要它们,则将它们声明为默认值(尽管默认值仍表示未声明),或者如果您不希望使用它们,则将其删除。
bolov

2
@bolov图表很有用,但这不能回答我的问题。我想找出哪些函数实际上是由编译器生成的。换句话说:我不是在问理论上应该发生什么,而是在实践中要发生什么。
Helge Klein

1
@ tjwrona1992:通过该参数,我们将不需要测试我们的代码,因为我们知道,如果编译器执行了与预期不同的任何操作,那么其中肯定有一个错误。
ruakh

1
@ tjwrona1992:是的,完全是。同样,查看编译器生成的内容不是验证编译器是否正确,而是验证您是否为编译器提供了正确的输入。
鲁阿赫

7

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

当然有。在Linux的(和其他Unix系统),可以使用nmreadelf并且objdump所生成的目标文件/库/可执行拆卸他们和检查任何导出的符号(以及更多)。

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


1
尽管这些工具可能无法很好地显示出可能生成了哪些函数(即允许编译器生成它们,但是您从未使用过这些函数,所以它决定不打扰,或者消除了链接时代码删除)
JMAA

@JMAA在大多数情况下,“允许生成但从未使用”在标准术语中表示函数是“隐式声明”但未“隐式定义”的。是的,即使禁用内联,这仍然意味着您将看不到符号。
aschepler

1
严格来说,此答案确实更准确地回答了以下问题:“编译器生成了哪些方法?” 这与不太精确的问题“编译器可能在不同的上下文中生成了哪些方法?”不同。
rici

@rici是的。但是更精确的问题并不容易回答,所以我去寻找可以回答的问题。如果您认为我的回答没有价值,请随意投票。
Jesper Juhl

1
@jesper:不,我已经投票了。正如我所说,我认为您回答的问题更为准确。另一个问题可能是出于意图,需要进行一些手动操作,因为这是事实,我们不知道它可能包含哪些假设上下文。但这是字面上提出的问题,无论有意还是无意,因此为回答这个问题而感到荣誉。
rici

1

目前这只是部分答案。

Visual Studio 2019

建设者

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

在此处输入图片说明

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.