热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

位域附近的变量会损坏吗?

如何解决《位域附近的变量会损坏吗?》经验,需要怎么解决?

我面临的问题与Linux内核社区所描述的问题非常相似- 由位域背叛

问题的实质在于,GCC发出64位读取访问以访问偶数1位位域。这会导致读取相邻字段的意外副作用,而该副作用可在程序的其他位置进行修改。当回写修改后的位域值时,相邻变量的旧值也会被回写,从而丢失其他线程对其所做的任何修改。

我的问题略有不同。我有这样的课程/结构-

class Group {

    uint8 adjVariable;
    volatile bool  flag1: 1;
    volatile bool  flag2: 1;
    // so on...
    volatile bool  flag10: 1;
};

访问这些变量的方式是-

Group::fun() {
    Group_Scoped_lock();
    // adjVariable was 12 here.
    if ( adjVariable > 0 ) {
        adjVariable = 0; // <------- EXPLICIT ZERO ASSIGNMENT
    }
    // some code that doesn't affect adjVariable 
    bool1 = false;
    bool2 = false;
    bool3 = false;
    assert( adjVariable == 0 ); // <---- This assert is tripping stating that adjVariable is 12!!
}

在我们怀疑与GCC发生“错误”之前,我验证了是否adjVariable在没有Group_lock()其他地方的情况下进行了访问。尽我所能,我看不到代码中发生这种情况的任何地方。

现在,由于编译器对位域发出64位读取并且它们是易失性的,如果它adjVariable作为该读取的一部分发出了to 的读取,并且显式的ZERO分配adjVariable仍在高速缓存中,因此我们为12读取了较早的值,该adjVariable怎么办?并且这个新读取的值会覆盖显式设置的值吗?因此,我们跳闸了assert?如果是这样,我该如何验证?

在本文中,他们讨论的是丢失对其他线程中完成的相邻变量的更新,但是在我的问题中,我怀疑由于内存中的读取而导致adjVariable同一线程中完成的更新的丢失。这可能吗?

我们正在使用古老的g ++编译器,该编译器在同样旧的Fedora版本12虚拟机上仅符合C ++ 98。另外,只有运行6个月的代码库才遇到此问题


推荐阅读
author-avatar
woaimm0705242
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有