C++ 作为结构访问数组与未定义行为

C++ 作为结构访问数组与未定义行为,c++,pointers,casting,undefined-behavior,C++,Pointers,Casting,Undefined Behavior,假设我们有一个包含4个float值的结构和一个包含4个元素的float数组 那么,作为Foo实例访问数组并通过该实例更改数组元素是否是未定义的行为 struct Foo { float a; float b; float c; float d; }; float values[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; int main() { auto& floats = *reinterpret_cast<Foo

假设我们有一个包含4个
float
值的结构和一个包含4个元素的
float
数组

那么,作为
Foo
实例访问数组并通过该实例更改数组元素是否是未定义的行为

struct Foo
{
    float a;
    float b;
    float c;
    float d;
};

float values[4] = { 1.0f, 1.0f, 1.0f, 1.0f };

int main()
{
    auto& floats = *reinterpret_cast<Foo*>(values);
    floats.a = 0.0f;
    floats.b = 0.0f;
    floats.c = 0.0f;
    floats.d = 0.0f;
}
structfoo
{
浮动a;
浮球b;
浮点数c;
浮动d;
};
浮点值[4]={1.0f,1.0f,1.0f,1.0f};
int main()
{
自动和浮动=*重新解释强制转换(值);
浮动。a=0.0f;
浮动。b=0.0f;
浮点数c=0.0f;
浮点数d=0.0f;
}

联机编译和运行:

是的,这确实是一种未定义的行为。它违反了所谓的严格别名规则,即禁止通过不相关的指针访问对象(除非特别要求,否则我不会在这里详细讨论不相关的内容)

但是,结构的浮点数组是不相关的

以下是标准(3.10/10)的摘录:

如果程序试图通过访问对象的存储值 行为为以下类型之一以外的glvalue 未定义:

-对象的动态类型

-对象动态类型的cv限定版本

-一种类似(例如)的类型 4.4)中定义的对象的动态类型

-一种 与的动态类型相对应的有符号或无符号类型 反对,

-对应于的有符号或无符号类型的类型 对象动态类型的cv限定版本

-包含上述类型之一的聚合或联合类型 在其元素或非静态数据成员中(递归地包括, 子集合或包含的元素或非静态数据成员 联盟)

-是的基类类型(可能是cv限定的)的类型 对象的动态类型

-字符或无符号字符类型


调用严格别名,严格别名,我们在第7行有一个调用。这怎么可能是定义良好的呢?您的每个类成员之间可能存在任意填充。@LightnessRacesinOrbit right。事实上,@LightnessRacesinOrbit在说别的话。比方说,用字符数组替换float数组,并开始以特定偏移量访问其中的元素,然后将float值复制到其中。该程序将是格式良好的,不会有未定义的行为。但是,由于填充的原因,您不太可能在结构中找到包含预期值的浮点成员。请详细说明一下?或者让我看看标准中的相关章节?谢谢@JohannGerell,我最喜欢的部分:给我3分钟。谢谢你对“无关”的阐述。我也有这种预感。“约翰尼格尔@约翰尼格尔C语言,它更容易被C++所允许,许多编译器允许在C++中使用它们作为编译器扩展。但是,不允许对齐结构和数组。