当前位置: 首页 > 知识库问答 >
问题:

如何通过指向非易失性的指针接收易失性?

宋奇希
2023-03-14

我正在使用一个API,该API为内存映射的I/O提供指针。它通过填写指针到指针的参数来实现这一点:

int map(void** p);

因为这是内存映射的I/O,所以我很确定我应该在这里使用易失性。(我不知道为什么他们没有将参数设为易失性ull**。)

但是,我的volatile void**不能隐式转换为函数的void**,因此我不能直接传入它:

volatile void* p;
map(&p); // Error: no known conversion from 'volatile void **' to 'void **'.

我目前正在使用一个额外的变量和一个单独的赋值步骤来解决这个问题:

volatile void* p;
void* pNonVolatile;
map(&pNonVolatile);
p = pNonVolatile;

这似乎很冗长。在这种情况下,当指针传入时,将volatile抛出是否安全?i、 e。

volatile void* p;
map(const_cast<void**>(&p));

共有1个答案

凤棋
2023-03-14

从C语言的角度来看,这可能会导致库中未定义的行为,但在使用const_cast的代码中不会。

然而,根据您所描述的,库可能不使用C或C来写入此内存空间(您提到它使用内存映射的I/O)。因此,如果库在没有volatile的情况下取消对指针的引用,那么可能存在的未定义行为是不相关的,因为硬件正在这样做,而不是软件。

在任何情况下,使用const\u cast或“额外指针然后分配”解决方案似乎都无关紧要。如果内存是由硬件设备写入的,它们应该都正常,但如果由库写入而没有易失性,则它们都不正常。

 类似资料:
  • C11 6.7.3类型限定符,第7段规定: 这里,指针的类型为,但我关心的是当实际指向的对象是非易失性的时会发生什么,特别是编译器是否可以将从对的单个访问转换为以下形式的两个访问: 这显然会使代码不正确。因此,目标是确定是否所有这样的指向对象实际上都需要。

  • 我对C和C++中语义的理解是,它将内存访问变成了(可观察到的)副作用。每当读取或写入内存映射文件(或共享内存)时,我都希望指针是volatile限定的,以表明这实际上是I/O。(John Regehr写了一篇关于语义的很好的文章)。 此外,我认为使用这样的函数访问共享内存是不正确的,因为签名表明volatile限定已被放弃,并且内存访问不被视为I/O。 在我看来,这是一个支持的论点,在这里vola

  • 在阅读了这个问题和这个(尤其是第二个答案)之后,我对volatile及其关于记忆障碍的语义感到非常困惑。 在上面的例子中,我们写入一个易失性变量,这会导致一个mitch,这反过来会将所有挂起的存储缓冲区/加载缓冲区刷新到主缓存,使其他缓存行无效。 然而,非易失性字段可以优化并存储在寄存器中,例如?那么,我们如何才能确保给定一个写入易失性变量之前的所有状态变化都是可见的呢?如果我们有1000件东西呢

  • 我对下面的代码段有一个问题。结果可能有一个结果[0,1,0](这是用JCStress执行的测试)。那么这是怎么发生的呢?我认为数据写入(data=1)应该在Actor2(guard2=1)中写入到guard2之前执行。我说得对吗?我问,因为很多时候我读到挥发物周围的说明没有重新排序。此外,根据这一点:http://tutorials.jenkov.com/java-concurrency/vola

  • 如果是,如果被添加到数组中,强制转换会受到什么影响?谢谢你! 编辑:@cacahuete Frito链接了一个非常相似的问题:带有'volatile'数组的'memcpy((void*)dest,src,n)'安全吗?

  • 来自C/C++,我对Java中的volatile对象行为有点困惑。 null faik,volatile意味着b引用的“book对象”应该在主内存中。编译器可能在内部实现引用作为指针,因此b指针可能位于缓存中。我的理解是,volatile是对象的限定符,而不是引用/指针的限定符。 问题是:在使用方法中,本地引用不是易失性的。这个“本地”引用会不会把底层的Book对象从主存带到缓存中,实质上使对象不