- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
如果 C 编译器填充结构以便将字段对齐到它们的 native 对齐方式,然后初始化该结构,填充是否初始化为零?
例如下面的结构:
typedef struct foo_t_ {
int a;
char b;
int c;
char d;
} foo_t;
在许多系统上,这个(设计不佳的)结构的 sizeof(foo_t)
为 16,总共有 6 个字节的填充,每个字符后有 3 个字节。
如果我们像这样初始化结构:
foo_t foo = { .a = 1, .b = '2' };
然后字段 foo.a
将设置为 1,foo.b
将设置为字符“2”。未指定的字段(`foo.c' 和 'foo.d')将自动设置为 0。问题是,填充的 6 个字节发生了什么?那也会自动设置为0吗?还是未定义的行为?
用例是我将计算数据结构的哈希值:
foo_t foo = { .a = 1, .b = '2' };
foo_t bar = { .a = 1, .b = '2' };
uint32_t hash_foo = calc_hash(&foo, sizeof(foo));
uint32_t hash_bar = calc_hash(&bar, sizeof(bar));
并且我想确保 hash_foo
和 hash_bar
相同。我可以通过首先使用 memset()
清除结构,然后初始化它们来保证这一点,但使用 C 初始化似乎更干净。
实际上,我系统上的 GCC 也会清除填充,但我不知道这是否能保证。
最佳答案
一般来说,根据 C11
,对于任何未初始化对象章节 §6.2.6.1/6,
When a value is stored in an object of structure or union type, including in a member object, the bytes of the object representation that correspond to any padding bytes take unspecified values.
但是,如果完成了部分 初始化,在这种情况下,对于其余 成员,初始化就像具有静态或线程存储持续时间的对象一样发生,然后,引用相同的标准,章节 §6.7.9/21
If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.
关于具有静态存储持续时间的对象的隐式初始化,第 10 段
If an object that has static or thread storage duration is not initialized explicitly, then:
- if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;
因此,在您的情况下,剩余对象的填充保证为 0,但对于已收到初始化程序的成员则不然。
因此,总而言之,您不应该依赖于 0 的隐式初始化,而应使用memset()
。
话虽这么说,无论如何,不建议(要求)依赖于填充字节,如果有的话。使用确切的成员变量并根据这些值计算散列。
关于c - C 是否将结构填充初始化为零?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37642026/
我是 Spring 新手,这就是我想要做的事情: 我正在使用一个基于 Maven 的库,它有自己的 Spring 上下文和 Autowiring 字段。 它的bean配置文件是src/test/res
我在我的测试脚本中有以下列表初始化: newSequenceCore=["ls", "ns", "*", "cm", "*", "ov", "ov", "ov", "ov", "kd"] (代表要在控
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Class construction with initial values 当我查看 http://en.
我得到了成员变量“objectCount”的限定错误。编译器还返回“ISO C++ 禁止非常量静态成员的类内初始化”。这是主类: #include #include "Tree.h" using n
我有如下所示的a.h class A { public: void doSomething()=0; }; 然后我有如下所示的b.h #include "a.h" class b: publi
我需要解析 Firebase DataSnapshot (一个 JSON 对象)转换成一个数据类,其属性包括 enum 和 list。所以我更喜欢通过传递 DataSnapshot 来手动解析它进入二
我使用 JQuery 一段时间了,我总是使用以下代码来初始化我的 javascript: $(document).ready( function() { // Initalisation logic
这里是 Objective-C 菜鸟。 为什么会这样: NSString *myString = [NSString alloc]; [myString initWithFormat:@"%f", s
我无法让核心数据支持的 NSArrayController 在我的代码中正常工作。下面是我的代码: pageArrayController = [[NSArrayController alloc] i
我对这一切都很陌生,并且无法将其安装到我的后端代码中。它去哪里?在我的页脚下面有我所有的 JS? 比如,这是什么意思: Popup initialization code should be exec
这可能是一个简单的问题,但是嘿,我是初学者。 所以我创建了一个程序来计算一些东西,它目前正在控制台中运行。我决定向其中添加一个用户界面,因此我使用 NetBeans IDE 中的内置功能创建了一个 J
我有 2 个 Controller ,TEST1Controller 和 TEST2Controller 在TEST2Controller中,我有一个initialize()函数设置属性值。 如果我尝
据我所知, dependentObservable 在声明时会进行计算。但如果某些值尚不存在怎么办? 例如: var viewModel ={}; var dependentObservable1 =
我正在阅读 POODR 这本书,它使用旧语法进行默认值初始化。我想用新语法实现相同的功能。 class Gear attr_reader :chainring, :cog, :wheel de
我按照 polymer 教程的说明进行操作: https://www.polymer-project.org/3.0/start/install-3-0 (我跳过了可选部分) 但是,在我执行命令“po
很抱歉问到一个非常新手的Kotlin问题,但是我正在努力理解与构造函数和初始化有关的一些东西。 我有这个类和构造函数: class TestCaseBuilder constructor(
假设我们有一个包含 30 列和 30 行的网格。 生命游戏规则简而言之: 一个小区有八个相邻小区 当一个细胞拥有三个存活的相邻细胞时,该细胞就会存活 如果一个细胞恰好有两个或三个活的相邻细胞,那么它就
我是 MQTT 和 Android 开放附件“AOA” 的新手。在阅读教程时,我意识到,在尝试写入 ByteArrayOutputStream 类型的变量之前,应该写入 0 或 0x00首先到该变量。
我有 2 个 Controller ,TEST1Controller 和 TEST2Controller 在TEST2Controller中,我有一个initialize()函数设置属性值。 如果我尝
我有一个inotify /内核问题。我正在使用“inotify” Python项目进行观察,但是,我的问题仍然是固有的关于inotify内核实现的核心。 Python inotify项目处理递归ino
我是一名优秀的程序员,十分优秀!