首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >位字段和序列点

位字段和序列点
EN

Stack Overflow用户
提问于 2012-02-06 02:04:38
回答 2查看 711关注 0票数 17

对于将f0f1打包到同一字节的实现,是否定义了下面的程序?

代码语言:javascript
复制
struct S0 {
       unsigned f0:4;
       signed f1:4;
} l_62;

int main (void) {
       (l_62.f0 = 0) + (l_62.f1 = 0);
       return 0;
}

我对C99和C11的答案很感兴趣,如果有理由认为它们是不同的。

在C99中,我发现的结果是6.5:2:

在前一个序列点和下一个序列点之间,对象的存储值最多应该通过表达式的求值

fi一次。..。

对我来说,这段话对上面的程序有什么影响还不清楚。

根据大量的随机化测试,大多数编译器似乎都会生成两个赋值不干扰的代码。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-06 04:43:45

C11将相邻的命名位字段视为同一内存位置的一部分。这样的位字段不能保证自动更新,换句话说,如果一个更新没有在另一个更新之前显式地排序,则行为是未定义的。然后,3.14 memory location还详细解释了何时可以认为两个字段位于不同的内存位置,因此可以独立考虑对它们的更新。

如果你想修改你的结构

代码语言:javascript
复制
struct S0 {
       unsigned f0:4;
       int :0;
       signed f1:4;
} l_62;

这样,在两个位字段之间有一个奇怪的“内存位置分隔符”,您的代码就可以保证是正确的。

对于C99来说,情况似乎更复杂,没有关于内存位置的详细概念。在最近关于linux内核邮件列表的一次讨论中,有一种说法是,通常对于所有位字段对,当更新其中任何一个字段时,都会保证原子性。讨论的起点是一个案例,在这个案例中,gcc以一种意想不到的方式污染了与位域相邻的非位域,导致了虚假崩溃。

票数 3
EN

Stack Overflow用户

发布于 2012-02-06 04:03:55

这里的赋值是给结构成员的。它们恰好共享相同的存储,这一事实不应该对逻辑产生影响。实际上,你并没有给同样的东西赋值。

当然,我不是语言律师。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9151608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档