George Robinson
George Robinson

Reputation: 2125

Why does the /Zc:twoPhase- compiler switch has no effect in MSVC?

Why doesn't the /Zc:twoPhase- compiler switch which follows the /permissive- switch cause the compilation errors to disappear in MSVC 19.13, just like they disappear when the /permissive-` switch is completely removed, with the following problem code ?

#include <stdio.h>

template <unsigned int BYTES>
class CBase
{
public:
    char Arr[BYTES];

    int Fn1(void) {
        return Arr[1] ^ Arr[sizeof(Arr)-1];
    }

    int Fn2(void) {
        return Arr[2] ^ Arr[sizeof(Arr)-2];
    }
};

template <unsigned int BYTES>
class CDerived : public CBase<BYTES>
{
public:

    int FnSum(void) {
        return Fn1() + Fn2() + Arr[0];  // ERRORs: identifiers "Fn1" and "Fn2" and "Arr" are NOT found !
    }
};    

int main(void)
{
    CDerived<32> ddd;

    printf("%d\n", ddd.Fn1());  //No error here
    printf("%d\n", ddd.Fn2());  //No error here
    printf("%d\n", ddd.FnSum());

    return (int)ddd.Arr[0];   //No error here
}

The above code compiles in MSVC v19.10 when the /permissive- switch is completely removed.
See: https://godbolt.org/g/Yxw89Y

NOTE: I cannot include a link to an example on http://godbolt.org with the /permissive- /Zc:twoPhase- switches together, because the latest Godbolt MSVC compiler (v19.10) is outdated and does not support the /Zc:twoPhase- compiler switch.

According to this article and this article, the compilation error in MSVC comes from the Two-Phase Name Lookup being enabled by the conformance to the C++ standard mode ( enabled by the /permissive- option).
Also, according to the former article: "The /permissive- option implicitly sets the conforming two-phase lookup compiler behavior, but it can be overridden by using /Zc:twoPhase- switch".
However adding the two compiler switches /permissive- /Zc:twoPhase- (in that order) does not override it and does not make the compilation errors disappear in MSVC v19.13.

For the Context of this problem, see this entry.

Upvotes: 1

Views: 3311

Answers (1)

Chuck Walbourn
Chuck Walbourn

Reputation: 41047

This code does build with the VS 2017 (15.7 update) version 19.14 when using /permissive-, so it was likely just a complier bug in VS 2017 (15.6 update) that has been fixed. You original code doesn't have anything to do with two-phase lookup.

If code errors out with /permissive-, and then builds with /permissive- /Zc:twoPhase- then it's two-phase related. Otherwise, it's just due to the conformance enforced by the /permissive- switch. See Give Visual C++ a Switch to Standard Conformance and Two-phase name lookup support comes to MSVC.

UPDATE It builds with x86 but not x64, which seems to reinforce the idea that this is a compiler bug and not a source conformance issue.

Upvotes: 1

Related Questions