struct test{ int num; }; int main(){ struct test t = {1234}; int n = *((int*)&t); // n = 1234 return 0; }
上面的代码段是否法律的并且不会导致未定义的行为?我在生产中看到过类似的代码片段。编辑:请原谅这里使用的C风格转换。
ktecyv1j1#
结构
struct test{ int num; };
是标准布局结构。保证其数据成员num在结构test中的偏移量为零。标准布局结构对于与用其他编程语言(例如用C)编写的代码进行通信是有用的。在C中,结构类型的对象的地址等于其第一个数据成员的地址。来自C标准(6.7.2.1结构和联合说明符)15在结构对象中,非位域成员和位域所在的单元的地址按它们声明的顺序递增。* * 一个指向结构对象的指针,经过适当的转换,指向它的初始成员**(或者如果该成员是位字段,则指向它所在的单元),反之亦然。结构对象中可能有未命名的填充,但在其开头没有。这段代码
num
test
int n = *((int*)&t);
有效且格式良好。最好使用C转换reinterpret_cast,而不是C转换。正如**@HolyBlackCat**在他的评论中指出的那样(例如C20标准,6.8.3复合类型)4两个对象a和b是指针可互换的,如果://...(4.3)- 一个是标准布局类对象,另一个是该对象的第一个非静态数据成员,或者,如果该对象没有非静态数据成员,则该对象的任何基类子对象(11.4),或者//...如果两个对象是指针可相互转换的,那么它们具有相同的地址,可以通过reinterpret_cast从指向另一个对象的指针中获取指向其中一个对象的指针
reinterpret_cast
1条答案
按热度按时间ktecyv1j1#
结构
是标准布局结构。保证其数据成员
num
在结构test
中的偏移量为零。标准布局结构对于与用其他编程语言(例如用C)编写的代码进行通信是有用的。
在C中,结构类型的对象的地址等于其第一个数据成员的地址。
来自C标准(6.7.2.1结构和联合说明符)
15在结构对象中,非位域成员和位域所在的单元的地址按它们声明的顺序递增。* * 一个指向结构对象的指针,经过适当的转换,指向它的初始成员**(或者如果该成员是位字段,则指向它所在的单元),反之亦然。结构对象中可能有未命名的填充,但在其开头没有。
这段代码
有效且格式良好。
最好使用C转换
reinterpret_cast
,而不是C转换。正如**@HolyBlackCat**在他的评论中指出的那样(例如C20标准,6.8.3复合类型)
4两个对象a和b是指针可互换的,如果:
//...
(4.3)- 一个是标准布局类对象,另一个是该对象的第一个非静态数据成员,或者,如果该对象没有非静态数据成员,则该对象的任何基类子对象(11.4),或者
//...
如果两个对象是指针可相互转换的,那么它们具有相同的地址,可以通过reinterpret_cast从指向另一个对象的指针中获取指向其中一个对象的指针