代码之家  ›  专栏  ›  技术社区  ›  T.E.D.

定义用于易失性和非易失性对象的例程

  •  1
  • T.E.D.  · 技术社区  · 14 年前

    我发现我自己想写一个例程,将操作两个易失性和非易失性内存块。大致如下:

    void byte_swap (unsigned * block_start, size_t amount) {
        for (unsigned * lp = block_start; lp < block_start + amount; lp++) {
            *lp = htonl(*lp);
        }
        memcpy (block_start, some_other_address, amount);
    }
    

    (不是我真正的代码,而是一个例子)。

    我遇到的问题是,如果我尝试使用指向易失性内存区域的指针,编译器会抱怨丢失了易失性限定符。我可以抛弃volatile,但如果例程试图缓存更改(或以前的读取),它似乎会使例程本身不安全,不是吗?

    另一种选择是让程序本身 unsigned volatile * ,但这需要我将所有非易失性调用程序转换为易失性指针。

    我想第三种选择是制作两个完全相同的例程副本,不同之处在于 volatile

    有什么问题吗 正确的方法 来处理这件事,如果是的话是什么?

    作为一个主要相关的问题,预定义例程(特别是memcpy)是否可以安全地与volatile指针一起使用?如果我这样做了,会有什么不好的事情发生在我身上?仅仅因为不使用volatile void指针,就必须自己重新运行任何与内存相关的库例程,这似乎有点愚蠢。

    2 回复  |  直到 14 年前
        1
  •  2
  •   doron    14 年前

    你只需要使用 volatile 在处理内存映射IO时,对同一内存地址的连续读写可以而且应该返回不同的值。如果您正在写入相当于简单共享内存的内容,那么一个简单的正式切换机制就足够了,该机制将访问分配给CPU或硬件设备(如DMA控制器)。

    还要注意,在非缓存内存或更糟的内存映射设备上执行操作将非常慢。在执行任何字节交换操作之前,最好先复制到正常的未缓存内存。在将大量数据复制到内存映射IO时,DMA可以为您提供大量CPU周期。

    不稳定的

        2
  •  1
  •   CB Bailey    14 年前

    尽管代码对于非易失性对象可能是悲观的(虽然给定了函数,但在本例中可能不是这样),但是您应该能够为 volatile unsigned* unsigned* . 就像 const 您可以添加 volatile 没有显式(并且可能有危险)转换的限定符。

    你不应该改变 全部的 不稳定的 来电者可以保持原样。

    尽管 memcpy 不稳定的 不稳定的 禁止不适用。你很可能会抛弃 不稳定的 内存 没有任何问题(除了那些你已经有不稳定的内存区域)。