【问题标题】:Is It Safe to Cast Away volatile?抛弃挥发物安全吗?
【发布时间】:2011-01-29 07:21:03
【问题描述】:

大多数时候,我都是这样做的。

class a {
public:
    ~ a() {
        i = 100;          // OK
        delete (int *)j;  // Compiler happy. But, is it safe?
                          // The following code will lead compilation error : delete j;
    }

private:
    volatile int i;
    volatile int *j;
};

int main() {
    a aa;

}

不过,我在这里看到一篇文章:

https://www.securecoding.cert.org/confluence/display/seccode/EXP32-C.+Do+not+access+a+volatile+object+through+a+non-volatile+reference

抛弃 volatile 允许访问 通过非易失性对象 参考。这可能导致 未定义的,也许是无意的 程序行为。

那么,我上面的代码示例的解决方法是什么?

这是我使用时收到的错误消息

删除 j

请注意,这是 VC6 的输出(不要问我为什么使用 VC6!)

c:\projects\a\a.cpp(5):错误 C2664: 'delete' : 无法转换参数 1 从 'volatile int *' 到 'void *' 转换失去限定符

【问题讨论】:

  • 为什么你认为它应该是易变的?
  • @Richard:自旋锁标志可以分配在普通内存中,但它是易失的。没那么疯狂。
  • 我不明白为什么delete j; 会是编译时错误。

标签: c++


【解决方案1】:

deletevolatile 意味着您已经序列化了对它的访问,因此实际上它不再是volatile。删除 volatile 的正确方法(一旦您知道它是安全的)是使用 const_cast<int*>

如果指针,而不是int,是易失性的,那么你的意思是int *volatile j。此外,如果一个类的所有成员都是 volatile,您可能希望一次限定整个对象,a volatile aa;

【讨论】:

    【解决方案2】:

    这取决于您对 volatile 变量的期望。现在,j 是一个指向易失整数的指针;你是这个意思吗?如果是这样,它是安全的,因为您不需要访问 volatile 值,只需访问它的地址,它不是 volatile。

    但是,如果您的意思是想要一个指向整数的 volatile 指针,则所需的语法是 int* volatile j。在这种情况下,首先将其转换为非volatile 指针可能会出现问题,但我认为如果您按原样尝试delete,您的编译器不会抱怨。一方面,G++ 没有。

    【讨论】:

      【解决方案3】:

      什么都没有。如果您不访问 volatile 内存,则 volatile 的语义不受影响。如果您通过强制转换的非易失性指针访问易失性内存,编译器可能会优化引用。如果值已更改,则您将获得错误的值。对于一些错误的值。 ;-)

      删除不会访问易失性内存,它只是释放它。与易失性存储器有关的一种不常见的事情。

      【讨论】:

      • 好吧,释放它通过允许new 返回相同的内存来授予其他所有人访问权限。因此,虽然它可能是允许的,但如果内存真的是易失性的,那肯定是不安全的。
      • Potatoswatter:是的,但是释放易失性内存意味着它首先是新的,否则这是一件坏事。我假设分配的内存在某种程度上是易失的。我怀疑它不是真的。
      【解决方案4】:

      这应该没问题,因为您在丢弃volatile 后并没有访问变量。但是,我不知道为什么无论如何都会出错。我自己尝试了该代码,一切似乎都很好,你看到发生了什么?

      【讨论】:

      • @Yan Cheng CHEOK:是的,我们有点猜到了。你能复制/粘贴错误吗?
      • @Yan,我是说我没有编译错误。如果我使用-Wall,甚至没有警告。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-26
      • 2016-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-13
      • 2019-05-03
      相关资源
      最近更新 更多