Is Visual Studio 2013 optimizing correctly in the presence of /OPT:ICF?

前端 未结 2 430
轻奢々
轻奢々 2020-12-03 13:52

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

相关标签:
2条回答
  • 2020-12-03 14:10

    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**)
    }
    

    Here f(int*) has a static variable s of type int and f(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. points out that /opt:noicf prevents the non-conforming behavior.

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

    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).

    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.

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

    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.

    and a later comment says:

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

    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.

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

    0 讨论(0)
  • 2020-12-03 14:20

    No, this optimization does not conform to the C++ standard. The declaration of uniqueMemLoc defines a unique object for each instance of the template, and each object has its own address.

    (If you had used a string literal, it would be a different story. The optimization would be valid in that case.)

    0 讨论(0)
提交回复
热议问题