SO是一场狗屎秀。感谢您的搭车。
根据 C++11 标准草案草案,这似乎不是一个有效的优化
14.8
[temp.fct.spec] 说(强调我的未来):
从模板实例化的每个函数模板专业化都有 它自己的任何静态变量的副本。 [ 示例:
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 规则。
T.C.指出
/opt:noicf
可以防止不合格行为。
Matt McNabb 指出 /OPT(优化)文档 包含以下注释:
因为/OPT:ICF会导致相同的地址被分配给 不同的函数或只读数据成员(const 变量 使用 /Gy 编译),它可以破坏依赖于唯一的程序 函数或只读数据成员的地址。了解更多 信息,请参阅 /Gy(启用功能级链接)。
这表明这可能是故意的不合格行为。 Ben Voigt 在评论中表示现在已转移到聊天,这确实意味着优化可能会不符合标准,但这一点是值得商榷的。
用户 usr 链接到 MS 博客文章:介绍‘/Gw’编译器开关,上面写着:
请注意,ICF 优化仅适用于相同的情况 COMDAT 的地址未被占用,并且它们是只读的。如果一个 数据未取地址,则通过 ICF 破坏地址唯一性 不会导致任何可观察到的差异,因此它是有效的并且 符合标准。
后来的评论说:
即使它本身就是完全标准的投诉,当 与 /Gy 结合可能会导致潜在的破坏行为。
据我所知,为了使
/Gy
生效 const 变量 __declspec(selectany) 必须使用,但在文档中可能会更清楚。
至少我们可以看到
/Gw
不应该引入不合格行为,但 /Gy
与 /Gw
结合可能会引入不合格行为。
不,这个优化不符合C++标准。
uniqueMemLoc
的声明为模板的每个实例定义了一个唯一的对象,并且每个对象都有自己的地址。
(如果您使用了字符串文字,那将是一个不同的故事。在这种情况下优化将是有效的。)