当询问C中常见的未定义行为时,灵魂比我提到的严格别名规则更加开明.
他们在说什么?
考虑一对相关结构的以下声明.后代类不添加任何成员变量,唯一的成员函数是一个构造函数,它不会做任何事情,只是将其所有参数转发给基类的构造函数.
struct Base {
Base(int a, char const* b):
a(a), b(b)
{ }
int a;
char const* b;
};
struct Descendant: Base {
Descendant(int a, char const* b):
Base(a, b)
{ }
};
Run Code Online (Sandbox Code Playgroud)
现在考虑使用这些类型的以下代码.函数foo期望接收一个数组Base.但是,main定义一个数组Descendant并将其传递给它foo.
void foo(Base* array, unsigned len)
{
/* <access contents of array> */
}
int main()
{
Descendant main_array[] = {
Descendant(0, "zero"),
Descendant(1, "one")
};
foo(main_array, 2);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
是否定义了该程序的行为?答案是否取决于它的主体foo,例如它是写入数组还是只读取它?
如果sizeof(Derived)不相等 …