代码之家  ›  专栏  ›  技术社区  ›  µBio

略显奇怪的C++代码

  •  6
  • µBio  · 技术社区  · 15 年前

    对不起,如果这很简单,我的C++是生锈的。

    这是干什么的?据我所见,没有赋值或函数调用。这个代码模式在我继承的一些代码中重复了很多次。如果重要的话,它是嵌入式代码。

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

    编辑:从那里继续,下面的附加代码确认了健康怀疑吗?(完全来自代码,包括重复,除了名字被更改以保护无辜者)

    if (!WaitForNotBusy(50)) 
        return ERROR_CODE_X;
    
    *(volatile UINT16 *)& someVar->something;
    
    if (!WaitForNotBusy(50)) 
        return ERROR_CODE_X;
    
    *(volatile UINT16 *)& someVar->something;
    x = SomeData;
    
    4 回复  |  直到 9 年前
        1
  •  19
  •   Michael Burr    15 年前

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

    所以表达;

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

    将在某个偏移量(由 something 结构元素的偏移量)。 someVar 指针。此读取将发生,并且由于 volatile 关键字。

    注意,一些设备寄存器执行一些功能,即使它们只是简单地被读取——即使数据读取没有被使用。这在状态寄存器中是很常见的,在读取指示特定位中错误状态的寄存器后,可能会清除错误条件。

    这可能是使用 不稳定的 关键字。

        2
  •  9
  •   Bill Lynch    15 年前

    所以这是一个远射。

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

        3
  •  9
  •   Heath Hunnicutt    15 年前

    我认为作者的意图是使编译器发出 记忆障碍 在这一点上。通过评估 不稳定的 ,编译器的指示是,不应将此表达式优化掉,并且应“实例化”在出现此习惯用法的每一行对易失位置(内存屏障、优化限制)的访问语义。

    这种类型的习惯用法可以“封装”在预处理器宏中。( #define )如果另一个编译有不同的方法来产生相同的效果。例如,能够直接对读或写内存屏障进行编码的编译器可能使用内置机制,而不是这种习惯用法。在宏中实现这种类型的代码可以更改整个代码基中的方法。

    编辑:用户sharth有一个很好的观点,如果此代码在指针地址为 身体的 而不是 事实上的 地址(或映射到特定物理地址的虚拟地址),然后执行此读取操作可能会导致外围设备发生某些操作。

        4
  •  -1
  •   Artyom    15 年前

    通常这是错误的代码。

    在C和C++中挥发物的手段非常少,不提供内隐记忆障碍。所以这段代码是完全错误的,如果它写为

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

    这只是错误的代码。

    费用: volatile 不使可变原子!

    Reed本文: http://www.mjmwired.net/kernel/Documentation/volatile-considered-harmful.txt

    这就是为什么 不稳定的 几乎不应该在正确的代码中使用。