我很惊讶地意外地发现以下工作:
#include <iostream>
int main(int argc, char** argv)
{
struct Foo {
Foo(Foo& bar) {
std::cout << &bar << std::endl;
}
};
Foo foo(foo); // I can't believe this works...
std::cout << &foo << std::endl; // but it does...
}
Run Code Online (Sandbox Code Playgroud)
我将构造对象的地址传递给它自己的构造函数.这看起来像源级别的循环定义.标准是否真的允许您在构造对象之前将对象传递给函数,还是这种未定义的行为?
鉴于所有类成员函数已经将指向其类实例的数据的指针作为隐式参数,我认为这并不奇怪.并且数据成员的布局在编译时是固定的.
请注意,我不是在问这是有用还是好主意; 我只是在修补一些关于课程的更多信息.
正如初始化所述,需要进行左值到右值的转换?是int x = x;UB吗?C++标准在3.3.2 声明部分中有一个令人惊讶的例子,其中a int用它自己的不确定值初始化:
Run Code Online (Sandbox Code Playgroud)int x = 12; { int x = x; }这里第二个x用它自己的(不确定的)值初始化.- 结束例子 ]
Johannes对此问题的回答表明是未定义的行为,因为它需要左值到右值的转换.
在最新的C++ 14草案标准中N3936,可以在此处找到此示例已更改为:
Run Code Online (Sandbox Code Playgroud)unsigned char x = 12; { unsigned char x = x; }这里第二个x用它自己的(不确定的)值初始化.- 结束例子 ]
C++ 14中有关于不确定值和未定义行为的变化,这些变化在示例中引发了这种变化吗?