json icon indicating copy to clipboard operation
json copied to clipboard

Tests don't build with VS 2026

Open t-b opened this issue 2 months ago • 7 comments

Description

no text

Reproduction steps

cmake -S . -B build -G "Visual Studio 18 2026" -A x64
cmake --build build

Expected vs. actual results

no text

Minimal code example

no text

Error messages

E:\projekte\json>cmake -S . -B build -G "Visual Studio 18 2026" -A x64
-- Selecting Windows SDK version 10.0.26100.0 to target Windows 10.0.26200.
-- The CXX compiler identification is MSVC 19.50.35717.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/18/Community/VC/Tools/MSVC/14.50.35717/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Using the multi-header code from E:/projekte/json/include/
-- Operating system: Windows-10.0.26200; MSYS_NT-10.0-26200 DESKTOP-A4CHLC0 3.6.5-22c95533.x86_64 2025-10-10 12:02 UTC x86_64 Msys
-- Compiler: Microsoft (R) C/C++-Optimierungscompiler Version 19.50.35717 für x64; Copyright (C) Microsoft Corporation. Alle Rechte vorbehalten.; ; Syntax: cl [ Option... ] Dateiname... [ /link Linkeroption... ]; MSVC_VERSION=1950; MSVC_TOOLSET_VERSION=145
-- C++ standard library: Microsoft C++ Standard Library (MSVC STL), _MSVC_STL_VERSION=145
-- Testing standards: 11 14 17 20 23
-- Looking for C++ include sys/types.h
-- Looking for C++ include sys/types.h - found
-- Looking for C++ include stdint.h
-- Looking for C++ include stdint.h - found
-- Looking for C++ include stddef.h
-- Looking for C++ include stddef.h - found
-- Check size of size_t
-- Check size of size_t - done
-- Configuring done (5.1s)
-- Generating done (0.4s)
-- Build files have been written to: E:/projekte/json/build



  unit-conversions.cpp
E:\projekte\json\tests\src\unit-conversions.cpp(1667,36): error C2672: "nlohmann::json_abi_v3_12_0::basic_json<std::map
,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::ve
ctor<uint8_t,std::allocator<uint8_t>>,void>::get": keine übereinstimmende überladene Funktion gefunden [E:\projekte\jso
n\build\tests\test-conversions_cpp17.vcxproj]
      E:\projekte\json\include\nlohmann\json.hpp(1813,10):
      kann "unknown-type nlohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,
  double,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint8_t>>,void>::
  get(void) noexcept" sein
          E:\projekte\json\tests\src\unit-conversions.cpp(1667,36):
          „unknown-type nlohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,d
  ouble,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint8_t>>,void>::g
  et(void) noexcept“: Das Vorlage-Argument für „__formal“ konnte nicht abgeleitet werden.
              E:\projekte\json\include\nlohmann\json.hpp(1812,68):
              "type": Kein Element einer direkten oder indirekten Basisklasse von "std::enable_if<false,int>"
      E:\projekte\json\include\nlohmann\json.hpp(1772,10):
      oder "unknown-type nlohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,
  double,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint8_t>>,void>::
  get(void) noexcept(<expr>) const"
          E:\projekte\json\tests\src\unit-conversions.cpp(1667,36):
          Fehler beim Spezialisieren der Funktionsvorlage „unknown-type nlohmann::json_abi_v3_12_0::basic_json<std::map
  ,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::
  vector<uint8_t,std::allocator<uint8_t>>,void>::get(void) noexcept(<expr>) const“
              E:\projekte\json\tests\src\unit-conversions.cpp(1667,36):
              Mit den folgenden Vorlagenargumenten:
                  E:\projekte\json\tests\src\unit-conversions.cpp(1667,36):
                  "ValueTypeCV=std::filesystem::path"
                  E:\projekte\json\tests\src\unit-conversions.cpp(1667,36):
                  "ValueType=std::filesystem::path"
              E:\projekte\json\include\nlohmann\json.hpp(1774,62):
              "nlohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,double,std
  ::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint8_t>>,void>::get_impl":
   keine übereinstimmende überladene Funktion gefunden
                  E:\projekte\json\include\nlohmann\json.hpp(1737,20):
                  kann "unknown-type nlohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int64
  _t,uint64_t,double,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint8
  _t>>,void>::get_impl(nlohmann::json_abi_v3_12_0::detail::priority_tag<4>) noexcept const" sein
                  E:\projekte\json\include\nlohmann\json.hpp(1724,16):
                  oder "nlohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,d
  ouble,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint8_t>>,void> nl
  ohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlo
  hmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint8_t>>,void>::get_impl(nlohmann::json_a
  bi_v3_12_0::detail::priority_tag<3>) const"
                  E:\projekte\json\include\nlohmann\json.hpp(1701,19):
                  oder "BasicJsonType nlohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int6
  4_t,uint64_t,double,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint
  8_t>>,void>::get_impl(nlohmann::json_abi_v3_12_0::detail::priority_tag<2>) const"
                  E:\projekte\json\include\nlohmann\json.hpp(1676,15):
                  oder "ValueType nlohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int64_t,
  uint64_t,double,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint8_t>
  >,void>::get_impl(nlohmann::json_abi_v3_12_0::detail::priority_tag<1>) noexcept(<expr>) const"
                  E:\projekte\json\include\nlohmann\json.hpp(1634,15):
                  oder "ValueType nlohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int64_t,
  uint64_t,double,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint8_t>
  >,void>::get_impl(nlohmann::json_abi_v3_12_0::detail::priority_tag<0>) noexcept(<expr>) const"

E:\projekte\json\tests\src\unit-conversions.cpp(1668,29): error C3536: "p": Kann nicht verwendet werden, bevor es initi
alisiert wurde. [E:\projekte\json\build\tests\test-conversions_cpp17.vcxproj]
E:\projekte\json\tests\src\unit-conversions.cpp(1677,36): error C2672: "nlohmann::json_abi_v3_12_0::basic_json<std::map
,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::ve
ctor<uint8_t,std::allocator<uint8_t>>,void>::get": keine übereinstimmende überladene Funktion gefunden [E:\projekte\jso
n\build\tests\test-conversions_cpp17.vcxproj]
      E:\projekte\json\include\nlohmann\json.hpp(1813,10):
      kann "unknown-type nlohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,
  double,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint8_t>>,void>::
  get(void) noexcept" sein
          E:\projekte\json\tests\src\unit-conversions.cpp(1677,36):
          „unknown-type nlohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,d
  ouble,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint8_t>>,void>::g
  et(void) noexcept“: Das Vorlage-Argument für „__formal“ konnte nicht abgeleitet werden.
              E:\projekte\json\include\nlohmann\json.hpp(1812,68):
              "type": Kein Element einer direkten oder indirekten Basisklasse von "std::enable_if<false,int>"
      E:\projekte\json\include\nlohmann\json.hpp(1772,10):
      oder "unknown-type nlohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,
  double,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint8_t>>,void>::
  get(void) noexcept(<expr>) const"
          E:\projekte\json\tests\src\unit-conversions.cpp(1677,36):
          Fehler beim Spezialisieren der Funktionsvorlage „unknown-type nlohmann::json_abi_v3_12_0::basic_json<std::map
  ,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::
  vector<uint8_t,std::allocator<uint8_t>>,void>::get(void) noexcept(<expr>) const“
              E:\projekte\json\tests\src\unit-conversions.cpp(1677,36):
              Mit den folgenden Vorlagenargumenten:
                  E:\projekte\json\tests\src\unit-conversions.cpp(1677,36):
                  "ValueTypeCV=std::filesystem::path"
                  E:\projekte\json\tests\src\unit-conversions.cpp(1677,36):
                  "ValueType=std::filesystem::path"
              E:\projekte\json\include\nlohmann\json.hpp(1774,62):
              "nlohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,double,std
  ::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint8_t>>,void>::get_impl":
   keine übereinstimmende überladene Funktion gefunden
                  E:\projekte\json\include\nlohmann\json.hpp(1737,20):
                  kann "unknown-type nlohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int64
  _t,uint64_t,double,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint8
  _t>>,void>::get_impl(nlohmann::json_abi_v3_12_0::detail::priority_tag<4>) noexcept const" sein
                  E:\projekte\json\include\nlohmann\json.hpp(1724,16):
                  oder "nlohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,d
  ouble,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint8_t>>,void> nl
  ohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int64_t,uint64_t,double,std::allocator,nlo
  hmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint8_t>>,void>::get_impl(nlohmann::json_a
  bi_v3_12_0::detail::priority_tag<3>) const"
                  E:\projekte\json\include\nlohmann\json.hpp(1701,19):
                  oder "BasicJsonType nlohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int6
  4_t,uint64_t,double,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint
  8_t>>,void>::get_impl(nlohmann::json_abi_v3_12_0::detail::priority_tag<2>) const"
                  E:\projekte\json\include\nlohmann\json.hpp(1676,15):
                  oder "ValueType nlohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int64_t,
  uint64_t,double,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint8_t>
  >,void>::get_impl(nlohmann::json_abi_v3_12_0::detail::priority_tag<1>) noexcept(<expr>) const"
                  E:\projekte\json\include\nlohmann\json.hpp(1634,15):
                  oder "ValueType nlohmann::json_abi_v3_12_0::basic_json<std::map,std::vector,std::string,bool,int64_t,
  uint64_t,double,std::allocator,nlohmann::json_abi_v3_12_0::adl_serializer,std::vector<uint8_t,std::allocator<uint8_t>
  >,void>::get_impl(nlohmann::json_abi_v3_12_0::detail::priority_tag<0>) noexcept(<expr>) const"

Compiler and operating system

VS 2026 x64 on Windows 11 x64 Pro

Library version

49026f799 (:arrow_up: Bump mkdocs-material from 9.6.23 to 9.7.0 in /docs/mkdocs (#4991), 2025-11-12)

Validation

t-b avatar Nov 14 '25 16:11 t-b

Strange. It's this test:

#ifdef JSON_HAS_CPP_17
#if JSON_HAS_FILESYSTEM || JSON_HAS_EXPERIMENTAL_FILESYSTEM
TEST_CASE("std::filesystem::path")
{
    SECTION("ascii")
    {
        json const j_string = "Path";
        auto p = j_string.template get<nlohmann::detail::std_fs::path>();
        json const j_path = p;

        CHECK(j_path.template get<std::string>() ==
              j_string.template get<std::string>());
    }

    SECTION("utf-8")
    {
        json const j_string = "P\xc4\x9b\xc5\xa1ina";
        auto p = j_string.template get<nlohmann::detail::std_fs::path>();
        json const j_path = p;

        CHECK(j_path.template get<std::string>() ==
              j_string.template get<std::string>());
    }
}
#endif

and it used to work with MSVC's earlier versions. This is the detection logic for filesystem:

#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM)
    #ifdef JSON_HAS_CPP_17
        #if defined(__cpp_lib_filesystem)
            #define JSON_HAS_FILESYSTEM 1
        #elif defined(__cpp_lib_experimental_filesystem)
            #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
        #elif !defined(__has_include)
            #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
        #elif __has_include(<filesystem>)
            #define JSON_HAS_FILESYSTEM 1
        #elif __has_include(<experimental/filesystem>)
            #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1
        #endif

        // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/
        #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8
            #undef JSON_HAS_FILESYSTEM
            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
        #endif

        // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support
        #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8
            #undef JSON_HAS_FILESYSTEM
            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
        #endif

        // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support
        #if defined(__clang_major__) && __clang_major__ < 7
            #undef JSON_HAS_FILESYSTEM
            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
        #endif

        // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support
        #if defined(_MSC_VER) && _MSC_VER < 1914
            #undef JSON_HAS_FILESYSTEM
            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
        #endif

        // no filesystem support before iOS 13
        #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000
            #undef JSON_HAS_FILESYSTEM
            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
        #endif

        // no filesystem support before macOS Catalina
        #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
            #undef JSON_HAS_FILESYSTEM
            #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM
        #endif
    #endif
#endif

nlohmann avatar Nov 17 '25 07:11 nlohmann

Both JSON_HAS_FILESYSTEM and JSON_HAS_EXPERIMENTAL_FILESYSTEM are set to 0 as JSON_HAS_CPP_17 is undefined. When I look in VS at the C++-Language standard setting of the projects this is everywhere set to C++14.

But the logic in the tests (cmake/tests.cmake) which iterate over CMAKE_CXX_COMPILE_FEATURES seem to think that C++17 is good.

So maybe this is more a cmake 4.2 issue than a VS 2026 one?

t-b avatar Nov 17 '25 16:11 t-b

I had a look at that issue. From what I understand, the "breaking change" is that Microsoft removed the experimental/filesystem header starting from the latest version of the STL (see https://github.com/microsoft/STL/pull/5765).

Here's the behaviour of the _MSVC_LANG macro according to https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-170

_MSVC_LANG Defined as an integer literal that specifies the C++ language standard targeted by the compiler. Only code compiled as C++ sets it. The macro is the integer literal value 201402L by default, or when the /std:c++14 compiler option is specified. The macro is set to 201703L if the /std:c++17 compiler option is specified. The macro is set to 202002L if the /std:c++20 compiler option is specified.

It means that if the C++ standard is not set via the compiler flag, it will default to C++14. Until that latest version of the STL, it was falling back to using the C++14 compatible experimental/filesystem header which was supported by MSVC.

I guess that compiling with the /std:c++20 should solve the issue, but I'm not sure how the library could do to automatically test with the different versions of the standard.

PerretDavid avatar Nov 17 '25 17:11 PerretDavid

Strange. test-conversions_cpp17 should be built with C++17, and since the test fails in line 1667, JSON_HAS_CPP_17 should be set and JSON_HAS_FILESYSTEM or JSON_HAS_EXPERIMENTAL_FILESYSTEM is set.

nlohmann avatar Nov 17 '25 19:11 nlohmann

I think you're right, it seems that intellisense doesn't show the right values in the editor when inside macro_scope.hpp.

I re-did a couple of tests: when in unit-conversions.cpp, JSON_HAS_CPP17 is 1, _MSVC_LANG is correctly set to 201703L, JSON_HAS_EXPERIMENTAL_FILESYSTEM is 0, JSON_HAS_FILESYSTEM is 1, so no issues on the compiler/supported standard front. Sorry about my previous message.

... oh and I just noticed that the MSVC team already opened an issue regarding the same problem here three weeks ago: https://github.com/nlohmann/json/issues/4974

PerretDavid avatar Nov 18 '25 09:11 PerretDavid

Strange. test-conversions_cpp17 should be built with C++17, and since the test fails in line 1667, JSON_HAS_CPP_17 should be set and JSON_HAS_FILESYSTEM or JSON_HAS_EXPERIMENTAL_FILESYSTEM is set.

My fault. test_conversions_cpp17 is compiled with C++17 according to the project properties:

Image

If I change the test code to be

diff --git a/tests/src/unit-conversions.cpp b/tests/src/unit-conversions.cpp
index 83d7e8d7c..e5aa72b1e 100644
--- a/tests/src/unit-conversions.cpp
+++ b/tests/src/unit-conversions.cpp
@@ -32,6 +32,8 @@ using nlohmann::json;
 #include <unordered_set>
 #include <valarray>

+#include <filesystem>
+
 // NLOHMANN_JSON_SERIALIZE_ENUM uses a static std::pair
 DOCTEST_CLANG_SUPPRESS_WARNING_PUSH
 DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors")
@@ -1664,7 +1666,7 @@ TEST_CASE("std::filesystem::path")
     SECTION("ascii")
     {
         json const j_string = "Path";
-        auto p = j_string.template get<nlohmann::detail::std_fs::path>();
+        auto p = j_string.template get<std::filesystem::path>();
         json const j_path = p;

         CHECK(j_path.template get<std::string>() ==
@@ -1674,7 +1676,7 @@ TEST_CASE("std::filesystem::path")
     SECTION("utf-8")
     {
         json const j_string = "P\xc4\x9b\xc5\xa1ina";
-        auto p = j_string.template get<nlohmann::detail::std_fs::path>();
+        auto p = j_string.template get<std::filesystem::path>();
         json const j_path = p;

         CHECK(j_path.template get<std::string>() ==

the compilation fails with the same error.

t-b avatar Nov 18 '25 10:11 t-b

If I change the test code to be [...] the compilation fails with the same error.

As shown below, the error message you had in the first post's build logs confirms that it was already resolving fine nlohmann::detail::std_fs::path as std::filesystem::path. I was wrong in my previous post.

E:\projekte\json\tests\src\unit-conversions.cpp(1667,36): Mit den folgenden Vorlagenargumenten: E:\projekte\json\tests\src\unit-conversions.cpp(1667,36): "ValueTypeCV=std::filesystem::path" E:\projekte\json\tests\src\unit-conversions.cpp(1667,36): "ValueType=std::filesystem::path"

The issue seems to be with the call of json::get with a std::filesystem::path argument and the way the templates are resolved by MSVC 2026 when using /std=c++17 (see https://github.com/nlohmann/json/issues/4974#issuecomment-3547180445)

PerretDavid avatar Nov 18 '25 12:11 PerretDavid