Give Visual C++ a Switch to Standard Conformance

This post was written by Gabriel Dos Reis, Phil Christensen, and Andrew Pardoe

The Visual C++ Team is excited to announce that the compiler in Visual Studio 2017 RC will feature a mode much closer to ISO C++ standards conformance than any time in its history. This represents a major milestone in our journey to full ISO C++ conformance. The mode is available now as an opt-in via the /permissive- switch but will one day become the default mode for the Visual C++ compiler.

Got a minute? Try Visual C++ conformance mode

The Visual C++ Team is previewing a compiler mode whereby longstanding non-conforming C++ constructs are rejected. This includes fixes to pre-C++11 non-conformance bugs that affect a significant amount of existing code. Examples are as simple as

In the definition of D::g, the symbol f is from the dependent base class B but standard C++ does not permit examining dependent base classes when looking for declarations that satisfy the use of f. That is an error in the source code that Visual C++ has long failed to diagnose. The fix is to prefix the call with this->. This fix works in both non-conformance and conformance modes.

The issue in this code sample might sound like a “two-phase name lookup” problem, but it is not quite that. In fact, two phase name lookup is the big missing piece from the first iteration of this standard conformance mode. Visual C++ does not support two-phase name lookup in VS 2017 RC but we expect to complete it early next year. When we do, the definition of /permissive- will change to include two-phase name lookup. This is an important point: /permissive- is not a completed feature in VS 2017 RC. You will have to keep your codebase clean as we complete our conformance work in Visual C++.

Opting into the conforming mode, /permissive-, during the series of VS 2017 update is a commitment to keeping your code base clean and to fixing non-conforming constructs we fix conformance issues in Visual C++. If you make your code compile with /permissive- today you may still have to make changes when VS 2017 releases, and again with updates to VS 2017 because we may have added more bug fixes for non-conforming behaviors.

The good news is this first release contains most of the big issues. With the exception of two-phase name lookup we don’t expect any major changes. See How to fix your code for a complete list of non-conforming constructs implemented under /permissive- today and how to fix them. We’ll update this list as we complete the changes.

From the Visual Studio IDE

In Visual Studio 2017 RC there is no setting in the project properties page for /permissive-. You’ll need to enter the switch manually under “Configuration -> C/C++ -> Additional Options”.

When compiling with /permissive-, the IDE compiler disables non-conforming Visual C++-specific behaviors and interprets your code following the C++ standard. You’ll notice that these language conformance features are now reflected in the areas of IDE such as IntelliSense and browsing features. In this example, setting /permissive- causes IntelliSense to flag default as an illegal identifier.

There are currently a few places where the IntelliSense in the IDE will conform better to the C++ standard than the Visual C++ compiler. For example, when relying on two-phase name lookup during overload resolution the compiler will emit an error. IntelliSense, however, will show that the code is conforming and will not give any red squiggles in the editor. You can see that happening in the screenshot below:

Why is that? You may know that Visual C++ uses a separate compiler for IDE productivity features. Since around 2009 we’ve used a compiler front-end from the Edison Design Group (EDG) to drive IntelliSense and many other features. EDG does a fantastic job at emulating other compilers–if you use Clang in Visual Studio (either through Clang/C2 or when targeting Android or iOS) we put EDG into “Clang mode” where it emulates Clang’s bugs and vendor-specific behaviors. Likewise, when using Visual C++, we put EDG into “Visual C++” mode.

While EDG emulates most VC++ features and bugs faithfully, there still might be some gaps due to the implementation being separate or how we integrated their compiler in the IDE. For example, we’ve implemented some features such as ignoring names from dependent base classes, but we haven’t yet implemented others, such as two-phase name lookup (“two-phase overload resolution” on this page) that are both implemented in EDG. Thus EDG shows the “complete” results IntelliSense even though the Visual C++ compiler doesn’t compile the code correctly.

Any differences you see in the IDE and the compiler are temporary. As we complete our conformance work the IDE and the compiler behaviors will match on all code.

Is there any relation to /Za?

The compiler switch /Za was an effort started decades ago to carve out a strictly portable behavior across several C++ compilers. The effort was stalled and we no longer recommend it for new projects. The switch /Za does not support certain key Microsoft SDK header files. By contrast /permissive- offers a useful conformance mode where input C++ code is interpreted according to ISO C++ rules but also allows conforming extensions necessary to compile C++ on targets supported by Visual C++. For example, you can use /permissive- with C++/CLI. The compiler switch /Za rejects a few non-conforming constructs; however the compiler switch /permissive- is our recommendation going forward for conforming code.

The road ahead

We know that conformance changes can be impactful to your code. In order to provide the best experience we’re splitting the development of /permissive- into three stages: the development stage, the adoption stage, on-by-default.

Development stage

The initial preview of /permissive- allows you to try out the switch and make most of the changes that will be required in your code. At this stage there will be some inconsistencies in the experience: the feature set under /permissive- will grow slightly, and editor features like IntelliSense may not match exactly. But all the changes you make to your code in this stage will work with and without /permissive-.

Adoption stage

The Visual C++ team will continue to add new conformance behavior under the /permissive- option throughout the Visual Studio 2017 release cycle. But we know that you rely on libraries and that those libraries also need to work with /permissive- in order for you to opt-in. Our first priority is to ensure that all public headers from our team, and those from Microsoft as a whole, compile cleanly with the /permissive- option. For example, the standard library headers compile correctly both with /permissive- and without. We are also working with the community to make changes to existing open source C++ projects (this typically involves removal of Visual C++-specific workarounds.)

On by default

When developers have had time to migrate their code to conform more closely to the C++ standards we will flip the default so that the compiler applies full ISO C++ standard rules when interpreting your source code. This won’t happen immediately–it’s a long-term goal for our conformance work. Until we make this switch—and at least for the entire Visual Studio 2017 cycle–you will have to opt-in to /permissive-. When we do switch it on by default your existing projects won’t change, but VS will make new projects opt-in to conformance.

Call to action

We encourage you to try the new option /permissive- in your projects. Please add this option to your build settings–either in the IDE or in your build scripts. If your code is already used cross-platform (i.e., it compiles with multiple compilers on many platforms) and does not contain Visual C++ specific workarounds, the chances are that the code will compile just fine with /permissive-!

If you do use Visual C++ specific, non-conforming constructs in your code, chances are that your code won’t compile the first time with /permissive-. There’s a list of patterns below of non-conforming C++ code, the typical error message/number you’ll see, and how to fix the code. The good news is that the fixes work both in the conforming mode and in the permissive mode. Therefore, if you try to compile with /permissive- and you correct issues, the corrected code will be good for the permissive mode too. This enables you to migrate your code to /permissive- incrementally, rather than making all of the changes at once.

How to fix your code

Here’s a list of behaviors that are affected by the permissive option in VS 2017. Note that this list is incomplete because the /permissive- switch is incomplete. As we add new conforming behaviors the potential breaking changes protected by /permissive- will expand. This means even if you fix your code to work with /permissive- today you may still have to make fixes in the future as we make Visual C++ conform better to the standard. Again, these changes will only affect your code if you opt-in by using the /permissive- switch.

Alternative tokens for logical operators (and, or, etc…)

//Can't use reserved names for variables:
// This includes the following:
// and and_eq bitand bitor compl not not_eq or or_eq xor xor_eq
static int and = 0; // Change name (possibly to 'and_')

Require unscoped enums to have an underlying type when pre-declared.

// The following line emits:error C3432: 'E': a forward declaration of an unscoped enumeration must have an underlying type
enum E; // Fix by changing to 'enum E : int'
void Foo(E val);
enum E // This should also have ': int' added to match the above declaration.
// This is not currently enforced by MSVC, but it is by other compilers.
{ A, B, C };

Binding a non-const reference to a temporary

struct S{};
// If arg is in 'in' parameter, then it should be made const.
void func(S& arg){}
int main() {
//error C2664: 'void func(S &)': cannot convert argument 1 from 'S' to 'S &'
//note: A non-const reference may only be bound to an lvalue
func( S() );
//Work around this by creating a local, and using it to call the function
S s;
func( s );
}

‘for each’ in native code

Defaulting conformance switches

The compiler switches /Zc:strictStrings and /Zc:rvalueCast are currently off by default, allowing non-conforming behavior. The switch /permissive- turns them on by default. You can pass in the /Zc flags after /permissive- to override this behavior if needed.

Changes not present in VS 2017 RTM

Here are some changes to /permissive- that we expect to enable in future releases and updates of VS 2017. This list may not be complete.

Two-phase name lookup

Error when binding a non-const reference to a temporary

Not treating copy init as direct init

Not allowing multiple user-defined conversions in initialization.

Alternative tokens for logical operators (‘and’, ‘or’, etc…)

Some changes have been made in the compiler and will be included in a future release of VS 2017. If you’re using unreleased compiler drops such as daily MSVC builds from NuGet, you will see these changes.

One reason scoped enumeration are preferred are because they have stricter type safety then unscoped enumerations. We were breaking that type safety in switch statements, which would allow you to accidently mix enumeration types. This can result in runtime behavior that was unexpected by the developer.

In closing

As always, we welcome your feedback. Please give us feedback about the /permissive- feature in the comments below or through e-mail at visualcpp@microsoft.com.

If you encounter other problems with Visual C++ in VS 2017 RC please let us know via the Report a Problem option, either from the installer or the Visual Studio IDE itself. For suggestions, let us know through UserVoice. Thank you!

Join the conversation

> EDG does a fantastic job at emulating other compilers–if you use Clang in Visual Studio (either through Clang/C2 or when targeting Android or iOS) we put EDG into “Clang mode” where it emulates Clang’s bugs and vendor-specific behaviors. Likewise, when using Visual C++, we put EDG into “Visual C++” mode.

What is the mechanism by which EDG is put into one mode or the other? Is it something the user can control? Specifically, can one force it into Clang mode even when not using Clang/C2?

The preprocessor may be under /permissive- or it may be under a different switch. If I had to guess, I’d say the latter because runaway preprocessor state is so broadly impactful and so hard to debug. But we haven’t discussed this as a team yet.

As for the Windows SDK, we’re working with the Windows team to get it /permissive- clean.

Looks like you have to fix a lot of stuff before this flag becomes really useful while developing native desktop apps. Affected are also MIDL generated stuff or macros like __FUNCTION__ and __FUNCDNAME__, which the C++ UnitTest Framework uses excessively.

We may eventually flag anonymous structs, but probably not for awhile because we are currently focusing on C++, and that is a C only. Until we spend time investigating it I am not sure how we would want to handle that in the Windows SDK. One possibility is to elevate “warning C4201: nonstandard extension used: nameless struct/union” to be level 1 or error by default rather than using “error C2467: illegal declaration of anonymous ‘struct'”, this would allow it to be suppressed in the SDK.

First, let me say that the EDG front end in IntelliSense catching more non-conforming behaviours than MSVC under /permissive- is not an issue; __it’s a feature__. Please place EDG in a mode as close to –strict as possible when /permissive- is set in the compiler options. If I activate this switch, it means I want to know about as many conformance issues as possible, through whatever means possible; having some squiggles in the editor is better than nothing.

One question: You mentioned /Zc:strictStrings and /Zc:rvalueCast as being on under /permissive-. What about /Zc:inline and /Zc:throwingNew? It would be great if we could rely on /permissive- turning on all /Zc switches, both current and future ones. Is this the plan?

The /permissive- switch is currently incomplete. Once we finish putting behaviors under that switch you’ll get compiler diagnostics for all conformance issues. That should prove more valuable than some squiggles that don’t match the compiler output. While I understand your believe that having squiggles is better than nothing, many developers value a consistent experience between the editor and the compiler diagnostic output. There are always tradeoffs to be made when your product is used by a large variety of developers.

We have all of the /Zc switches on our backlog. Look for updates when VS 2017 releases.

I understand the tradeoff in this case, and I value consistency too. A lot. But they’re already inconsistent, so we might as well reap some benefits from them being consistently inconsistent :-).

Seriously, I think a case can be made for the benefits of seeing more information about conformance issues in client code during this transition period. Interested developers could start fixing their code even before MSVC starts flagging it under /permissive-. Perhaps enabling that through an option in the IDE could be worth exploring?

Anyway, I want to make it clear that this is meant as a constructive suggestion, not criticism in any way. I’m very happy with the way things are shaping up for MSVC and VS; they’ve never looked better.

Back to technical stuff, I’ve just found out that in the EDG front end included with the RC the –ms_extensions option doesn’t recognize the __make_integer_seq intrinsic, which means won’t compile under that option (unless some other compatibility options are enabled as well). I know this is not directly relevant to how IntelliSense uses EDG, but would you mind passing this on to the relevant people (unless it’s a known issue)?

But how can we use C++11/14 standard features with MSVC++ in libraries when __cplusplus macro is still 199711L and only part of features is available? Always use C++98 in such libraries? Or deal with hell of #ifdef’s/#if _MSC_VER >= …?

VC++ is the only of modern mainstream compilers which ignores SD-6. And, ironically, this macros are most vital when using VC++ due the lack of standard conformance… :-(

is seems in current VS2017RC /permissive- enables “Alternative tokens for logical operations” as well.
but currently it conflicts with inline assembly, and/or/xor x86 opcodes produce ‘bad token’ errors during compile.

I thought I fixed this before the latest VS2017RC. Are you able to reproduce it on http://webcompiler.cloudapp.net/ with /permissive-? If you can, then will you please send me a repro? My email address is philc ‘at’ Microsoft dot com.

We gave /permissive- a try. Our code worked almost flawlessly with it, since we’ve had to keep compatibility with other compilers. The idea was to use /permissive- to forbid accidental addition of MS extensions.

Unfortunately, the problem was that some MS Windows SDK headers don’t compile with the flag. Is there an effort to fix them for upcoming releases?

I’m glad to hear /permissive- works for you! Keeping your code compiling with /permissive- will be a big help as the MSVC compiler moves away from vendor-specific extensions.

We are working with the C++ ecosystem–both OSS libraries like Boost and Windows headers–to make sure that they compile cleanly with /permissive-. Expect an announcement about the Windows SDK headers being /permissive- clean later this year.

If there are other libraries that you depend upon–either popular OSS libraries or proprietary libraries that your code relies upon–please urge their maintainers/authors to reach out to our team.

That issue got marked as could not reproduce, but from a reading of the code it seems plain that the usages of __if_exists and __if_not_exists in atlcom.h and atldbcli.h all suffer from “lookup members in dependent base”. In the offending constructor for CAccessorRowset that leads to the nullptr deref, there’s an “__if_exists(m_nAccessors)”, but that member is meant to come from a base class that is passed in as a template argument.

As a mini repro, https://godbolt.org/g/ap7AHE
First compiler output is something analogous to the atlcom and atlcomdbcli issues without /permissive-. Second compiler output is with /permissive-. Third output is with /permissive- and a possible fix (that may be complex in to actually implement in all of the cases if the implicit type isn’t known). First pane clearly shows 2 calls to puts in main as desired, second shows emptiness as undesired, third shows 2 calls to puts restored.

Hi,
Is it worth to report issues in SDK/WDK?
Is Microsoft willing to change prototypes functions in SDK/WDK or it is frozen?

We use 10.0.16299 and we still think there are function that prototype could be changed.
Especially there are function documented in MSDN as [in], SAL annotated as _In_ but with type LPTSTR/LPSTR/LPWSTR.
I think they could have type LPCTSTR/LPCSTR/LPCWSTR

It is quite ambiguous when you see argument with types
_In_ LPTSTR
_In_ LPSTR
_In_ LPWSTR