有些奇怪的C++代码

µBi*_*Bio 6 c c++ embedded

对不起,如果这很简单,我的C++就生锈了.

这是做什么的?据我所知,没有任何分配或函数调用.在我继承的一些代码中,这个代码模式重复了很多次.如果重要的是嵌入式代码.

*(volatile UINT16 *)&someVar->something;
Run Code Online (Sandbox Code Playgroud)

编辑:从那里继续,以下附加代码是否确认了希思的怀疑?(完全来自代码,包括重复,除了名称已被更改以保护无辜者)

if (!WaitForNotBusy(50)) 
    return ERROR_CODE_X;

*(volatile UINT16 *)& someVar->something;

if (!WaitForNotBusy(50)) 
    return ERROR_CODE_X;

*(volatile UINT16 *)& someVar->something;
x = SomeData;
Run Code Online (Sandbox Code Playgroud)

Mic*_*urr 19

这是嵌入式编程中相当常见的习惯用法(尽管它应该封装在一组函数或宏中),其中需要访问设备寄存器.在许多体系结构中,设备寄存器被映射到存储器地址,并且像任何其他变量一样被访问(尽管在固定地址处 - 可以使用指针,或者链接器或编译器扩展可以帮助修复地址).但是,如果C编译器没有看到对变量访问的副作用,它可以将其优化 - 除非变量(或用于访问变量的指针)被标记为volatile.

所以表达;

*(volatile UINT16 *)&someVar->something;
Run Code Online (Sandbox Code Playgroud)

将从something存储在someVar指针中的地址以某个偏移量(由结构元素的偏移量提供)发出16位读取.由于volatile关键字,将发生此读取并且编译器无法对其进行优化.

请注意,某些器件寄存器即使只是简单地读取它们也会执行某些功能 - 即使没有使用其他数据也是如此.这在状态寄存器中非常常见,其中在读取指示特定位中的错误状态的寄存器之后可能清除错误条件.

这可能是使用volatile关键字的常见原因之一.


Hea*_*utt 9

我认为作者的意图是让编译器在这些点上发出内存障碍.通过评估volatile的表达式结果,对编译器的指示是该表达式不应该被优化掉,并且应该"实例化"访问每个行的易失性位置(​​内存障碍,优化限制)的语义.习语出现了.

这种类型的习惯用法可以"封装"在预处理器宏(#define)中,以防另一个编译具有不同的方式来产生相同的效果.例如,具有直接编码读取或写入内存屏障能力的编译器可能使用内置机制而不是此习惯用法.在宏中实现此类代码可以在整个代码库中更改方法.

编辑:用户sharth有一个很好的观点,如果此代码在指针的地址是物理地址而不是虚拟地址(或映射到特定物理地址的虚拟地址)的环境中运行,那么执行此读取操作可能会导致一些在外围设备上的动作.

  • 此外,一个宏可以让它更明显地发生了什么...(#define READ_MEMORY_BARRIER ...) (2认同)

Bil*_*nch 9

所以这是一个很长的镜头.

如果该地址指向FPGA或其他设备上的存储器映射区域,那么当您读取该地址时,该设备可能实际上正在执行某些操作.