编译器是不是允许修改填充字节
Posted
技术标签:
【中文标题】编译器是不是允许修改填充字节【英文标题】:Is the compiler allowed to modify padding bytes编译器是否允许修改填充字节 【发布时间】:2022-01-14 10:48:56 【问题描述】:假设我有一个这样的代码 sn-p(并假设我在评论中说插入了填充):
#include "stdint.h"
struct A
uint8_t x;
// 3 bytes of padding
uint32_t y;
;
void foo(struct A* a)
a->x = 0;
是否允许编译器清除填充字节或对函数 foo 中的填充字节做任何事情?
https://en.cppreference.com/w/c/language/object 对此问题保持沉默,这让我相信是的,允许编译器执行此操作....
我想知道是否允许编译器这样做的原因是我想memcmp
两个结构,我想知道我可以假设什么......
【问题讨论】:
你为什么不直接明确声明填充? @RobertHarvey 这是一个解决方案,但如果我不需要,我不一定想这样做 您可以假设,编译器实现可以随意添加填充字节,并且字节数量可能因版本而异,这称为 ABI 更改。一般来说,您根本不应该使用 memcpy 来复制结构,因为您应该使用默认生成的复制构造函数。在内部,编译器通常会为较大的结构生成一个 memcpy,以便在需要时复制和调用构造函数。如果只使用 POD,则不需要构造函数调用。与其维护对构造函数/析构函数的需求,不如让编译器单独完成它的工作! 显式声明填充有一些好处。追随你的程序员不会有你刚才提出的同样问题。 @RobertHarvey 但是你不能便携。 【参考方案1】:是的。 C 2018 6.2.6.1 6 说:
当一个值存储在结构或联合类型的对象中时,包括在成员对象中,对应于任何填充字节的对象表示的字节采用未指定的值......
【讨论】:
它是否适用于(嗯,听起来像......)从一个struct
对象到另一个 memcpy
-ing?就像memcmp
跟随memcpy
可以产生非零结果吗?
@EugeneSh.:我认为紧跟在memcpy
之后的memcmp
必须表示相等。
@EricPostpischil 你确定吗?尽管“未指定”意味着编译器供应商可以选择要放入填充的内容,但他们可能会选择不覆盖填充字节,因此它们可能包含垃圾。 (当然memcpy
会复制垃圾,所以memcmp
是对的)以上是关于编译器是不是允许修改填充字节的主要内容,如果未能解决你的问题,请参考以下文章