C++;11允许(不要求)释放/获取volatile关键字的语义 自从Visual C++ 2005以来,微软对C++代码不要求的代码> > Value类型进行了额外的排序保证。 P> C++中的任何东西实际上都禁止这些保证吗?我似乎这么认为

C++;11允许(不要求)释放/获取volatile关键字的语义 自从Visual C++ 2005以来,微软对C++代码不要求的代码> > Value类型进行了额外的排序保证。 P> C++中的任何东西实际上都禁止这些保证吗?我似乎这么认为,c++,visual-c++,c++11,language-lawyer,C++,Visual C++,C++11,Language Lawyer,请让我知道该标准是否允许Microsoft实施订购,并对该错误报告进行表决: 只要满足标准规定的要求,实现当然可以做超出要求的事情。向volatile对象添加release/acquire语义肯定在范围之内。我不认为C++委员会有兴趣改变语义(我们现在只是开始讨论波特兰C++的新一周,现在就讨论如何组织会议)。 < P>标准要求对易受攻击对象的访问严格按照抽象机器的规则进行评估,这大致意味着“不要优化”,但仅此而已。例如,不允许编译器在寄存器中缓存值或执行公共子表达式消除。它必须完全按照你说

请让我知道该标准是否允许Microsoft实施订购,并对该错误报告进行表决:


只要满足标准规定的要求,实现当然可以做超出要求的事情。向
volatile
对象添加release/acquire语义肯定在范围之内。我不认为C++委员会有兴趣改变语义(我们现在只是开始讨论波特兰C++的新一周,现在就讨论如何组织会议)。

< P>标准要求对易受攻击对象的访问严格按照抽象机器的规则进行评估,这大致意味着“不要优化”,但仅此而已。例如,不允许编译器在寄存器中缓存值或执行公共子表达式消除。它必须完全按照你说的去做

因此,对于所有标准的注意事项,
volatile
具有
内存\u顺序\u松弛的
语义(它没有指定任何不同)。当然,这并不意味着不允许您执行更严格的操作

微软编译器(如Ben Voigt所指出的,自2005年以来)一直将
volatile
视为获取/发布,这导致许多人假设“volatile==threadsafe”,这反过来又导致许多文章将其转化为“volatile是无用的!”和“volatile是邪恶的”


MS建议使用ISO实现的可能原因是,这使他们的编译器的行为与其他编译器一样,不再令人感到意外。

MSDN文档在ISO Compliant部分中也指出:“C++11ISO标准代码中的volatile关键字仅用于硬件访问;在我看来,这意味着根据C++03标准,volatile将用于进程间通信。这就是他们的意思吗?@John:我相信他们使用的短语“C++11 ISO标准代码”是指“可移植代码,可与任何C++11编译器正确工作”“。使用
volatile
进行线程(进程间或进程内)从来都不是可移植的。顺便说一句,C++03标准根本没有太多地讨论进程或线程。@John:我认为他们无意暗示这一点。他们将符合C++11标准的程序与用于实现C++11和C++03的程序进行比较,语义为/volatile:ms。他们没有将C++11与C++03进行比较。volatile所要求的是,对volatile对象的每次读取都会导致实际读取,对volatile对象的每次写入都会导致实际读取对象导致实际写入。这可以通过每个内存可见性工具想要添加的内容来增强:该标准只对I/O和
volatile
变量的影响提出了一些要求,作为其可观察的行为。向volatile添加release/acquire语义不会减少对可观察行为的保证。当然,要真正观察到对
volatile
对象的更改,您需要从程序外部观察它。这就是我的想法。因此,总而言之,“允许但不要求对易失性变量提供获取/释放保证。依赖此类保证的代码将是不可移植的。”@BenVoigt:请注意,实现可以向标准添加保证这一事实并不意味着依赖于这些额外保证的程序符合标准(根据标准,您的程序仍然可以有未定义的行为,即使在特定的实现中,行为可能已完全定义)@David:编译器是兼容的……它提供了标准要求的所有保证,并正确编译和执行根据标准编写的代码(也就是说,行为是根据标准定义的)。我们并不认为在文档中包含关于实现特定行为和可移植性的注释是一个坏主意。问题是该行为是否“不符合ISO标准”参加会议的人很快就投票了:我所说的微软人说这是一个“doc bug”,称之为“不符合”。他们认为这是一个符合标准的扩展,但没有一个用户应该依赖(有委员会成员无意中听到了那些认为行为有误的讨论)。因此,使用
/volatile:iso
可以神奇地找到所有比赛条件?“令人讨厌的惊喜”在实现之间移动时是常见的,并且摆脱获取/释放语义并没有改变它。它所做的改变是优化器可以自由地释放更快的代码序列。而且,微软编译器并没有总是将<代码>易失性/代码>作为获取/释放,它开始在Visual C++ 2005中这样做。(就像我在问题中所说的)。不,它不会“神奇地”做任何事情(这是许多人过去对
volatile
关键字的看法).
/volatile:iso
只会使编译器的行为与所有其他编译器一样,这就不那么令人困惑了。如果您使用其他东西编译代码,您的代码不会突然出现错误行为,因为您不依赖“魔法”。没有两个编译器的行为完全相同。竞争条件总是有可能被某个特定的实现隐藏。仅仅因为代码通过了
/volatile:iso
下的测试并不意味着它严格符合要求,所以“不再有令人讨厌的惊喜”就没有意义。@BenVoigt:他们错过了一个技巧,反而发出了警告,“您似乎正在使用
volatile
,您是否考虑过