Tho*_*ing 24 c++ optimization c++11 visual-studio-2013
我希望以下程序一直返回0.但是,对于Visual Studio 2013(Update 4),程序在发布版本中退出1.我不确定这是一个错误,还是编译器的优化器是正确的,并且依赖于某些边缘行为.如果关闭CONST宏,则release exe返回0.如果优化器确实正确,我是否可以获得允许它发出代码的原因?
#if 1
# define CONST const
#else
# define CONST
#endif
class TypeId {
public:
bool operator== (TypeId const & other) const
{
return id == other.id;
}
private:
TypeId (void const * id)
: id(id)
{}
public:
template <typename T>
static TypeId Get ()
{
static char CONST uniqueMemLoc = 0;
return TypeId(&uniqueMemLoc);
}
private:
void const * id;
};
int main(int, char **)
{
typedef int A;
typedef unsigned int B;
if (TypeId::Get<A>() == TypeId::Get<B>()) {
return 1;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Sha*_*our 15
根据草案C++ 11标准部分14.8 [temp.fct.spec]所说,这似乎不是一个有效的优化(强调我的未来):
从模板实例化的每个函数模板特化都有自己的任何静态变量的副本.[例如:
Run Code Online (Sandbox Code Playgroud)template<class T> void f(T* p) { static T s; }; void g(int a, char* b) { f(&a); // calls f<int>(int*) f(&b); // calls f<char*>(char**) }这里f(int*)有一个int类型的静态变量s,f(char**)有一个char*类型的静态变量s. - 末端的例子]
由于您获取变量的地址折叠它们会影响可观察的行为,这会违反as-if规则.
TC指出可以/opt:noicf防止不合规行为.
Matt McNabb指出/ OPT(优化)文档包含以下注释:
因为/ OPT:ICF可以将相同的地址分配给不同的函数或只读数据成员(使用/ Gy编译的const变量),它可以破坏依赖于函数或只读数据成员的唯一地址的程序.有关更多信息,请参阅/ Gy(启用功能级链接).
这表明这可能是故意的不符合行为.Ben Voigt 在一篇评论中表示现在转向聊天,这确实意味着优化可能不符合要求,但这一点值得商榷.
用户usr 链接到MS博客文章:介绍'/ Gw'编译器开关,它说:
请注意,ICF优化仅适用于未采用其地址的相同COMDAT,并且它们是只读的.如果数据没有被采用,那么ICF破坏地址唯一性将不会导致任何可观察到的差异,因此它是有效的并且符合标准.
以后的评论说:
即使它是完全标准的投诉,当与/ Gy结合时,可能会导致破坏行为.
从我所知道的为了/Gy影响const变量,必须使用__declspec(selectany),但在文档中可以更清楚.
至少我们可以看到不/Gw应该引入不符合要求的行为,而是/Gy与/Gwmay 结合使用.
不,这种优化不符合C++标准.声明为uniqueMemLoc模板的每个实例定义一个唯一对象,每个对象都有自己的地址.
(如果您使用了字符串文字,那将是一个不同的故事.在这种情况下,优化将是有效的.)
| 归档时间: |
|
| 查看次数: |
1341 次 |
| 最近记录: |