在/OPT:ICF 存在的情况下,Visual Studio 2013 是否正确优化?

2023-05-09C/C++开发问题
1

本文介绍了在/OPT:ICF 存在的情况下,Visual Studio 2013 是否正确优化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

限时送ChatGPT账号..

我希望以下程序始终返回 0.但是,对于 Visual Studio 2013(更新 4),程序在发布版本中退出 1.我不确定这是否是一个错误,或者编译器的优化器是否正确并且依赖于某些边缘行为.如果关闭了 CONST 宏,则发布 exe 返回 0.如果优化器确实正确,我能否得到允许它发出代码的原因?

I expect the following program to return 0 all of the time. However with Visual Studio 2013 (Update 4), the program exits 1 in release builds. I'm not sure if this is a bug or if the compiler's optimizer is correct and is relying on some edge behavior. If the CONST macro is turned off, the release exe returns 0. If the optimizer is indeed correct, could I get the reason why it is allowed to emit the code it does?

#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;
}

推荐答案

根据 C++11 标准部分草案 14.8 [temp.fct.spec] 说(强调我的未来):

This does not seem like a valid optimization according to the draft C++11 standard section 14.8 [temp.fct.spec] says (emphasis mine going forward):

从模板实例化的每个函数模板特化都有它自己的任何静态变量的副本.[示例:

Each function template specialization instantiated from a template has its own copy of any static variable. [ Example:

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.—结束示例]

Here f(int*) has a static variable s of type int and f<char*>(char**) has a static variable s of type char*. —end example ]

由于您采用折叠变量的地址,它们会影响可观察的行为,这将违反 假设规则.

Since your taking the address of the variable folding them effects observable behavior which would violate the as-if rule.

T.C.指出 /opt:noicf 可以防止不符合规范的行为.

T.C. points out that /opt:noicf prevents the non-conforming behavior.

Matt McNabb 指出 /OPT(优化)文档 包含以下注释:

Matt McNabb points out that the /OPT (Optimizations) documentation contains the following note:

因为/OPT:ICF 会导致相同的地址被分配给不同的函数或只读数据成员(常量变量使用/Gy 编译),它可以破坏依赖于唯一性的程序函数或只读数据成员的地址.更多信息,请参阅/Gy(启用功能级链接).

Because /OPT:ICF can cause the same address to be assigned to different functions or read-only data members (const variables compiled by using /Gy), it can break a program that depends on unique addresses for functions or read-only data members. For more information, see /Gy (Enable Function-Level Linking).

这表明这可能是故意的不合规行为.Ben Voigt 在评论中说现在转移到聊天,这确实意味着优化可能不符合,但这一点值得商榷.

Which suggests this could be intentional non-conforming behavior. Ben Voigt says in a comment now moved to chat that this indeed means the optimizations can be non-conforming but this points is debatable.

用户 usr 已链接 到 MS 博客帖子:介绍'/Gw'编译器开关,它说:

User usr linked to an MS blog post: Introducing ‘/Gw’ Compiler Switch and it says:

请注意,ICF 优化仅适用于相同的其地址未被采用的 COMDAT ,并且它们是只读的.如果一个数据不是地址获取,然后由 ICF 破坏地址唯一性不会导致任何可观察到的差异,因此它是有效的并且符合标准.

Please note, the ICF optimization will only be applied for identical COMDATs where their address is not taken, and they are read only. If a data is not address taken, then breaking address uniqueness by ICF won't lead to any observable difference, thus it is valid and conformant to the standard.

后来的评论说:

即使它完全符合自己的标准,当结合/Gy 可能会导致潜在的破坏行为.

Even though it's on it's own completely standards complaint, when combined with /Gy potentially breaking behavior can result.

据我所知,为了使 /Gy 生效 const 变量 __declspec(selectany) 必须使用,但它可能是文档中更清楚.

From what I can tell in order for /Gy to effect const variables __declspec(selectany) has to be used but it could be clearer in the documentation.

至少我们可以看到 /Gw 不应该引入不符合规范的行为,但 /Gy/Gw 结合可能会.

At minimum we can see that /Gw should not introduce non-conforming behavior but /Gy in combination with /Gw may.

这篇关于在/OPT:ICF 存在的情况下,Visual Studio 2013 是否正确优化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

The End

相关推荐

无法访问 C++ std::set 中对象的非常量成员函数
Unable to access non-const member functions of objects in C++ std::set(无法访问 C++ std::set 中对象的非常量成员函数)...
2024-08-14 C/C++开发问题
17

从 lambda 构造 std::function 参数
Constructing std::function argument from lambda(从 lambda 构造 std::function 参数)...
2024-08-14 C/C++开发问题
25

STL BigInt 类实现
STL BigInt class implementation(STL BigInt 类实现)...
2024-08-14 C/C++开发问题
3

使用 std::atomic 和 std::condition_variable 同步不可靠
Sync is unreliable using std::atomic and std::condition_variable(使用 std::atomic 和 std::condition_variable 同步不可靠)...
2024-08-14 C/C++开发问题
17

在 STL 中将列表元素移动到末尾
Move list element to the end in STL(在 STL 中将列表元素移动到末尾)...
2024-08-14 C/C++开发问题
9

为什么禁止对存储在 STL 容器中的类重载 operator&amp;()?
Why is overloading operatoramp;() prohibited for classes stored in STL containers?(为什么禁止对存储在 STL 容器中的类重载 operatoramp;()?)...
2024-08-14 C/C++开发问题
6