首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C编译器对位域做了什么?

C编译器对位域做了什么?
EN

Stack Overflow用户
提问于 2010-07-21 21:46:22
回答 6查看 3.1K关注 0票数 8

我正在做一个嵌入式项目(PowerPC目标,Freescale Metrowerks Codewarrior编译器),其中的寄存器是内存映射的,并在很好的位域中定义,以便轻松地旋转单个位标志。

目前,我们正在使用此功能清除中断标志并控制数据传输。虽然我还没有注意到任何bug,但我很好奇这是否安全。有没有什么方法可以安全地使用位域,或者我需要把每个位域都包装在DISABLE_INTERRUPTS中……ENABLE_INTERRUPTS?

需要说明的是: micro提供的报头具有如下字段

代码语言:javascript
复制
union {
        vuint16_t R;
        struct {
            vuint16_t MTM:1;        /* message buffer transmission mode */
            vuint16_t CHNLA:1;      /* channel assignement */
            vuint16_t CHNLB:1;      /* channel assignement */
            vuint16_t CCFE:1;       /* cycle counter filter enable */
            vuint16_t CCFMSK:6;     /* cycle counter filter mask */
            vuint16_t CCFVAL:6;     /* cycle counter filter value */
        } B;
    } MBCCFR;

我假设在位域中设置一个位不是原子的。这是一个正确的假设吗?编译器实际上会为位域生成什么类型的代码?自己使用R(原始)字段执行掩码可能更容易记住操作不是原子的(很容易忘记像CAN_A.IMASK1.B.BUF00M = 1这样的赋值不是原子的)。

非常感谢您的建议。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-07-21 21:49:50

原子性取决于目标和编译器。例如,AVR-GCC尝试检测位访问,并在可能的情况下发出位设置或清除指令。检查汇编程序的输出以确保...

编辑:这是一个直接从PowerPC上获取原子指令的资源:

http://www.ibm.com/developerworks/library/pa-atom/

票数 3
EN

Stack Overflow用户

发布于 2010-07-21 21:50:36

假设设置位域不是原子的,这是正确的。C标准对如何实现位域并不特别清楚,不同的编译器对位域的实现方式也各不相同。

如果你真的只关心你的目标架构和编译器,反汇编一些目标代码。

通常,您的代码将实现所需的结果,但效率远低于使用宏和移位的代码。也就是说,如果您不关心这里的性能,那么使用位字段可能更具可读性。

如果您担心将来的程序员(包括您自己)会感到困惑,那么您可以为原子的位编写一个setter包装器函数。

票数 3
EN

Stack Overflow用户

发布于 2010-07-21 21:56:58

是的,你的假设是正确的,因为你可能不会假设原子性。在特定的平台上,您可能会将其作为额外服务获取,但在任何情况下都不能依赖它。

基本上,编译器会为您执行掩码和其他操作。他也许能够利用转角案例或特殊指示。如果你对效率感兴趣,看看你的编译器生成的汇编程序,通常它是非常有指导意义的。作为一个经验法则,我想说现代编译器生成的代码与中等编程工作的效率一样高。对于你的特定编译器来说,真正深入的比特转换可能会给你带来一些好处。

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

https://stackoverflow.com/questions/3299897

复制
相关文章

相似问题

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