考虑这个程序:
#include <stdio.h>
struct S {
S() { print(); }
void print() { printf("%p\n", (void *) this); }
};
S f() { return {}; }
int main() { f().print(); }
Run Code Online (Sandbox Code Playgroud)
据我所知,这里只S构建了一个对象.没有副本省略:首先没有副本被删除,事实上,如果我明确删除了副本和/或移动构造函数,编译器继续接受该程序.
但是,我看到打印了两个不同的指针值.发生这种情况是因为我的平台的ABI在CPU寄存器中返回了一些可复制的类型,例如这个类型,因此ABI无法避免复制.clang即使在完全优化掉函数调用时也会保留这种行为.如果我给出S一个非平凡的复制构造函数,即使它不可访问,那么我确实看到相同的值打印两次.
print()在构造期间发生的初始调用,即在对象生命周期开始之前,但this在构造函数内部使用通常是有效的,只要它不以需要构造完成的方式使用 - 没有强制转换为例如派生类 - 据我所知,打印或存储其值不需要构造完成.
标准是否允许此程序打印两个不同的指针值?
注意:我知道该标准允许该程序打印相同指针值的两个不同表示,从技术上讲,我没有排除这一点.我可以创建一个避免比较指针表示的不同程序,但它会更难理解,所以我想尽可能避免这种情况.