C++标准对间接运算符保证内存写入的描述是不是已经优化了?

sha*_*oth 13 c++ compiler-construction optimization indirection compiler-optimization

这基本上是这个问题的延续.到目前为止看起来如果我有这样的函数:

void SecureZeroMemory( void* ptr, size_t cnt )
{
   volatile char *vptr = (volatile char *)ptr;
   while (cnt) {
       *vptr = 0;
       vptr++;
       cnt--;
   }
}
Run Code Online (Sandbox Code Playgroud)

并称之为:

{
    char buffer[size];
    SecureZeroMemory( buffer, size );
}
Run Code Online (Sandbox Code Playgroud)

那么因为buffer没有声明volatile,所以使用指向volatile的指针并不重要 - 数据本身不是易失性的,所以写入变量不构成可观察的行为(1.9/6),并允许编译器优化它们.

然而,最近我发现一个声明,它只是重要的指针声明.具体来说,C++ 03 5.3.1/1描述了间接(*),如下所示:

一元*运算符执行间接[...]如果表达式的类型是"指向T的指针",则结果的类型为"T".

所以声称是因为在volatile char*我们的get volatile char和write 上使用间接确实构成了可观察的行为,并且不再重要的是如何声明实际数据.

C++ 03 5.3.1/1间接描述是否真的保证使用volatile T*上面示例中的指针覆盖内存构成可观察行为并且不允许进行优化?

Ste*_*sop 4

我很确定“新”引用添加的只是*vptr一个类型为 的左值表达式volatile char

\n\n

左值的类型不会影响该左值表达式所引用的对象的类型,这与指向非 const 对象的指向 const 的指针不会以某种方式使该对象成为 const 的原因相同。因此,最初的分析不会影响这句话——该对象仍然不具有易失性限定类型。

\n\n

用通常的说法,我们会说 的类型是*vptrvolatile char &但 5/5 说,“如果一个表达式最初的类型为 \xe2\x80\x9c,引用 T\xe2\x80\x9d,则该类型先于 T 调整为 T任何进一步的分析”。这就是为什么*vptr说有 type volatile char,而不是volatile char &- 在分析任何表达式之前,您从类型中删除引用,即使它是左值。

\n\n

[编辑:我的答案曾经有一些关于简历资格对于整数类型的非对象值来说无关紧要的文本。这是真的(非类类型的左值到右值转换丢弃 cv 限定符,4.1/1)但无关紧要(我错误地认为,因为您引用的文本提到了非引用类型,所以它正在谈论此后的类型转换)]

\n