__cplusplus macro and MS Visual C++

closed account (E0p9LyTq)
In VC++ 2015 and 2017 there are property switches to set the C++ language standard.

No matter which standard is chosen -- /std::c++14, /std:c++17, /std:latest -- __cplusplus is set to 199711L.

MS has known about the bug for over a year, and has no plans to correct it until the C++ "compiler fully conforms to the standard."

https://blogs.msdn.microsoft.com/vcblog/2016/06/07/standards-version-switches-in-the-compiler/

If someone needs to know what language standard set the _MSVC_LANG macro has to be checked.

*OUCH* That could break a lot of existing code.
Last edited on
If you care about portability you shouldn't be using the very latest features anyway, so you wouldn't even bother checking that macro. So yes, code that's not very portable will break when ported.
closed account (E0p9LyTq)
If you care about portability you shouldn't be using the very latest features anyway

I hope you are suggesting to not use /std:latest, instead of /std:17 or /std:14. The only features I would want or need to use is those contained in an official standard release.

I don't consider /std:latest to represent such a release.
Last edited on
I'm saying that your code should ideally compile on the major compilers without specifying any special flags.
closed account (E0p9LyTq)
Then why bother having any standard at all. There are features added to newer standards and other features in older standards deprecated and/or removed in later standards.

std::random_shuffle vs. std::shuffle for one example.

constexpr for another example.

Portability shouldn't be a catch-all for not using features a certain standard can provide. IMO.
In an ideal world publishing a standard and implementing a standard would be the same action. In the real world, where most code is actually run, implementations may lag behind on compliance, or they may be buggy, or you may be forced to use an old version of a toolchain on a particular platform for compatibility reasons.
I'm not saying you should use features not in the standard, I'm saying to ensure potability you should use a lowest common denominator of standard features.

If you don't care about portability then sure, use whatever you want, up to and including compiler extensions. I think it's unwise, but to each his own.
closed account (E0p9LyTq)
@LB,

Thank you for reporting this!

Though it took more than a few weeks to fix the problem, it was "broke" years ago.

It will require an update to VC++2017 to get it working correctly. I hope that is released real soon.

Sucks when a feature that should be standard C++ is bollixed.

The real world is catching up to the ideal world.

The blog does confirm something I was guessing was true because of the VC++2017 language switches in a project's C/C++ property sheets:

Note that the MSVC compiler does not, and never will, support a C++11, C++03, or C++98 standards version switch.

The blog article has a link to a new switch in VC++2017, /permissive-.

Forces ISO Standard Conformance, and is set active by default.

I was somewhat wondering what the switch did when active/inactive (lazy to go look), and thanks to you, LB, I know. :)
https://docs.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance

As with all things MS and VS it isn't all beer and skittles:
Not all C++11, C++14, or C++17 standards-conforming code is supported by the Visual C++ compiler in Visual Studio 2017.

Every major compilers has an area or two not fully compliant with the standard(s). VS is not unique in that area.

Still getting used to all the features of VS2017, even after using it for several months.
closed account (E0p9LyTq)
If you don't care about portability then sure, use whatever you want, up to and including compiler extensions. I think it's unwise, but to each his own.

I want to use only what is allowed by the standard, be it C++14 or C++17. That is why IMO knowing what standard switch is used is vital.

If you define being strict conformant to a C++ standard as being non-portable, and you seem to do so, then not my problem.

I have looked at some 3rd party source that checks for C++ standard versions, expressly refusing to compile if the __cplusplus macro is set to "199711L" value.

Until this fix LB mentioned goes live with the next VS upgrade any code like that compiled using VS2015 or VS207, no matter what language standard the programmer sets, WILL FAIL TO COMPILE.

Even should the code be strict portable by current standards.
Last edited on
If you define being strict conformant to a C++ standard as being non-portable
Well, that depends on your definition of "standard" and the particular set of platforms that you're required to support in order to achieve the "portable" property.
For example, implementations for portable (in the sense of "can be physically carried by a human being") platforms are often behind the latest language features by a few years. I remember back in 2009 the homebrew PSP SDK was still using <iostream.h>. A couple years ago when I was dabbling in Android, the GCC implementation of the NDK, to name once thing, had std::unique_ptr but not std::shared_ptr (or the other way around).
Embedded platforms are probably much, much worse.

If you only want to support the latest few versions of Linux and Windows then being "portable" is easy, but there are weirder platforms out there with much shoddier support for the bleeding edge.
But you don't need to take my word for it, just read what Mozilla has to say on the subject of writing portable C++: https://developer.mozilla.org/en-US/docs/Mozilla/Using_CXX_in_Mozilla_code
That guide used to be much more restrictive a few years ago.
Last edited on
closed account (E0p9LyTq)
@helios,

You started out arguing for portability, and ended up arguing against it.

JB "solved" the issue I started this post about by linking to a blog post that MS is fixing the problem.

I'm done.

Ciao.
Last edited on
You started out arguing for portability, and ended up arguing against it.
I don't know what you mean, or perhaps your definition of "portability" is different from mine.

By the way, are you taking offense at my disagreeing with you? If you don't want to talk about this anymore that's fine, but the tone of your reply seems somewhat impolite. I don't think I was ever rude to you (at least not in these two threads; I couldn't remember much further back if I wanted to), so I don't know why you're being like this.
If it really is just my contrary opinion that bothers you then maybe it would be best not to post on Internet forums anymore. Just saying.
closed account (E0p9LyTq)
@LB,

reading further your link it looks like the proposed fix is still half-arsed. You have to set two switches to get the macro properly set, the /Zc:__cplusplus switch and /std:c++ switch.

Better than not fixing it, but it is a MS "solution."

@helios,
I am not taking offense, never did. I am just done discussing something that is already solved.

The topic was very specific, and didn't IMO need a lot of theory back and forth.

If you disagree, then not a whole lot I can say other than "I'm done."
@FurryGuy their plan is to eventually make the /Zc:__cplusplus switch be on by default, but they want to give projects time to fix code that incorrectly assumes MSVC always uses the broken behavior.
closed account (E0p9LyTq)
@LB, as I said, half-arsed. :)

Half a fix is still better than none, I can appreciate the amount of code that relies of broken behavior.

I remember when part of the Windows source code was released. Yow, that was a mess of kludges. Many popular software packages relied on undocumented bad MS coding from previous Windows versions and MS kept the legacy code hanging around.

MS released VS update 15.6.6 today, it wasn't active yesterday.

Checked the __cplusplus macro, still "199711L".

I really wasn't expecting a change yet. The blog post did say 15.7 update.
Topic archived. No new replies allowed.