1

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.

George Robinson
  • 1,500
  • 9
  • 21
  • So the error appears once you add `/permissive-` (as it isn't valid C++) and then goes away when you further add `/Zc:twoPhase-`? That sounds like what the excerpt you provided says. The latter overrides the conforming behaviour of the former. The question is confusing to me because the beginning seems to say `/Zc:twoPhase-` doesn't remove the error, but the end seems to say it does. – chris May 14 '18 at 14:56
  • Yes, the error appears when I add the `/permissive-` switch, but it does NOT disappear when I add the `/Zc:twoPhase-` switch. – George Robinson May 14 '18 at 15:01
  • Why not simply make the code two phase lookup compliant rather than trying to suppress the warning and continue using the invalid code? – Jesper Juhl May 14 '18 at 15:33
  • @Jesper: Making the code compliant with two-phase lookup is the subject of [this question](https://stackoverflow.com/questions/50321788/a-better-way-to-avoid-public-member-invisibility-and-source-code-bloat-repetitio) - not this one. – George Robinson May 14 '18 at 16:49

1 Answers1

1

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.

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81
  • I just checked how the x64 MSVC compiler v19.14.26428.1 behaves with this problem code and here are the results: Without the `/permissive-` option it compiles without errors, with the `/permissive-` option it does not compile and with both `/permissive- /Zc:twoPhase-` options it does not compile either. I tried to compile from the command line and from the VS IDE the results were the same. What is your evidence that this behavior has NOTHING to do with the two-phase lookup besides the `/Zc:twoPhase` switch having no effect ? BTW: You quoted an article, that I linked in my original question – George Robinson May 14 '18 at 20:23
  • If it only fails in x64 and not x86, then it's definitely a compiler bug. – Chuck Walbourn May 14 '18 at 20:35
  • I did not try the x86 version because I get a missing DLL error: ...\VC\Tools\MSVC\14.14.26428\bin\Hostx64\x86>cc.bat Microsoft (R) C/C++ Optimizing Compiler Version 19.14. Copyright (C) Microsoft Corporation. All rights reser src.cpp c1xx: fatal error C1356: unable to find mspdbcore.dll – George Robinson May 14 '18 at 20:39
  • If you can show that this behavior has NOTHING to do with the two-phase lookup besides the /Zc:twoPhase switch having no effect, then I will be forced to marked your reply as "the answer". But I don't want to mark an answer which states that this code compiles fine with the `/permissive-` switch, which I cannot verify, so please divide your reply into two parts, so I can mark only the one, I agree with.. – George Robinson May 14 '18 at 20:46
  • 1
    Try the x86 compiler version of the compiler and see for yourself. It only happens with the x64 compiler with ``/permissive-``. – Chuck Walbourn May 14 '18 at 21:26