请考虑以下代码:
#include <iostream>
struct foo
{
// (a):
void bar() { std::cout << "gman was here" << std::endl; }
// (b):
void baz() { x = 5; }
int x;
};
int main()
{
foo* f = 0;
f->bar(); // (a)
f->baz(); // (b)
}
Run Code Online (Sandbox Code Playgroud)
我们期望(b)崩溃,因为x空指针没有相应的成员.在实践中,(a)不会崩溃,因为this从不使用指针.
因为(b)取消引用this指针((*this).x = 5;),并且this为null,程序进入未定义的行为,因为取消引用null总是被称为未定义的行为.
会(a)导致未定义的行为吗?如果两个函数(和x)都是静态的呢?
c++ standards-compliance null-pointer undefined-behavior language-lawyer
考虑以下一对相互引用类型:
struct A;
struct B { A& a; };
struct A { B& b; };
Run Code Online (Sandbox Code Playgroud)
这可以通过GCC,Clang,Intel,MSVC中的聚合初始化来初始化,但不能通过SunPro来初始化,因为SunPro坚持要求用户定义的ctors.
struct {A first; B second;} pair = {pair.second, pair.first};
Run Code Online (Sandbox Code Playgroud)
这个初始化合法吗?
更详细的演示:http://ideone.com/P4XFw
现在,听从Sun的警告,用户定义的构造函数的类怎么样?以下适用于GCC,clang,Intel,SunPro和MSVC,但它是否合法?
struct A;
struct B { A& ref; B(A& a) : ref(a) {} };
struct A { B& ref; A(B& b) : ref(b) {} };
struct {B first; A second;} pair = {pair.second, pair.first};
Run Code Online (Sandbox Code Playgroud)
最后,如果容器也不是微不足道的,例如(在G ++,Intel,Clang(带警告)中工作,但不是MSVC(初始化器中未知的"配对")或SunPro("配对不是结构")
std::pair<A, B> pair(pair.second, pair.first);
Run Code Online (Sandbox Code Playgroud)
从我所看到的情况来看,§3.8[basic.life]/6禁止在生命周期开始之前访问非静态数据成员,但是对于第二次"对"第二次"访问"的左值评估是什么?如果是,那么这三个初始化都是非法的吗?另外,§8.3.2[dcl.ref]/5说"引用应该被初始化以引用一个有效的对象",这可能使所有三个都是非法的,但也许我错过了一些东西,编译器接受这个是有原因的.
PS:我意识到这些课程在任何方面都不实用,因此语言律师标签.这里相关且稍微更实际的旧讨论: …