nlohmann / json

JSON for Modern C++
https://json.nlohmann.me
MIT License
42.35k stars 6.67k forks source link

MSVC build failure with /Zc:__cplusplus and C++17 #1883

Closed djewsbury closed 4 years ago

djewsbury commented 4 years ago

On develop branch (commit bde57124187c5732c026ffb9357c0491344c45e7), MSVC will fail to compile if C++17 is disabled and the /Zc:__cplusplus is set.

The compile error seems reasonable:

json.hpp(6122): error C2416: attribute 'deprecated("Since 3.0.0")' cannot be applied in this context
json.hpp(8065): note: see reference to class template instantiation 'nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberUnsignedType,NumberFloatType,AllocatorType,JSONSerializer>' being compiled
json.hpp(6370): error C2416: attribute 'deprecated("Since 3.0.0")' cannot be applied in this context

Here, the "deprecated" attribute is begin applied to a "friend" declaration. There are free operators after the friend declaration (which presumably is what the attribute is supposed to bind to). But since this is technically a friend declaration and not really an operation declaration, MSVC doesn't seem to like it.

In a couple of other places, for static methods, JSON_HEDLEY_DEPRECATED() is compiled correctly.

Hedley seems to be hiding this issue somewhat, due to the behaviour of the cplusplus define in MSVC. Quite oddly, cplusplus is set to 199711L by default in MSVC, even when C++17 compilation is enabled. Hedley only reads the __cplusplus macro and interprets that as meaning that the compiler only supports C++98, and so disables the deprecated attribute entirely.

However, we can enable the /Zc:cplusplus compiler option to make the cplusplus macro behave in a more standard (or at least more clang/GCC-compatible) way. This causes Hedley to apply the attribute, and the error appears.

There's more info about this oddity in the compiler here: https://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus?view=vs-2019

I've worked around it with this block:

#include <nlohmann/thirdparty/hedley/hedley.hpp>
#undef JSON_HEDLEY_DEPRECATED
#define JSON_HEDLEY_DEPRECATED(X)
#include <nlohmann/json.hpp>

Also, when not using the /Zc:__cplusplus option it compiles fine (even when C++17 is enabled). That's not convenient for me to do, though, because it would have to apply for every source file that includes json.hpp

dconnet commented 4 years ago

I've noticed the same thing, only it appears to compile properly in VS2019. Only VS2017 fails (only 2 versions I currently use). I have "/Zc:cplusplus" set and cplusplus is at 201402L for both compilers.

t-b commented 4 years ago

Duplicate of https://github.com/nlohmann/json/issues/1695.

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.