Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warnings C4715 and C4127 when building json-3.9.1 with Visual Studio 2019 16.7.7 #2592

Closed
1 task done
Andreas-Schniertshauer opened this issue Jan 14, 2021 · 16 comments · Fixed by #2875
Closed
1 task done
Assignees
Labels
kind: bug platform: visual studio related to MSVC release item: 🔨 further change solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@Andreas-Schniertshauer
Copy link

Andreas-Schniertshauer commented Jan 14, 2021

I get the following warnings when building json-3.9.1 with Visual Studio 2019 16.7.7:

single_include\nlohmann\json.hpp(4697): warning C4715: 'nlohmann::detail::hash<nlohmann::basic_json<std::map,std::vector,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,bool,__int64,unsigned __int64,double,std::al
locator,nlohmann::adl_serializer,std::vector<unsigned char,std::allocator<unsigned char> > > >': not all control paths return a value
test\src\unit-json_pointer.cpp(362,78): warning C4127: conditional expression is constant

Please describe the steps to reproduce the issue.

  1. Download json-3.9.1.zip and unzip
  2. Open a Developer command Prompt v16.7.7
  3. cd json-3.9.1
  4. Create directory build and cd build
  5. cmake ..\ -D JSON_Install:BOOL=OFF -D JSON_ImplicitConversions:BOOL=OFF -D JSON_BuildTests:BOOL=ON
  6. cmake --build .

What is the expected behavior?

No warnings

And what is the actual behavior instead?

Warnings

Which compiler and operating system are you using?

  • Compiler: Visual Studio 2019 16.7.7 Professional
  • Operating system: Windows 10 2004 Pro German

Which version of the library did you use?

  • latest release version 3.9.1
@nlohmann
Copy link
Owner

Warning

single_include\nlohmann\json.hpp(4697): warning C4715: 'nlohmann::detail::hash<nlohmann::basic_json<std::map,std::vector,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,bool,__int64,unsigned __int64,double,std::al
locator,nlohmann::adl_serializer,std::vector<unsigned char,std::allocator<unsigned char> > > >': not all control paths return a value

seems to be a false positive, because function hash(const BasicJsonType& j) uses a an exhaustive switch statement where all reachable branches return a value. The default branch consists of an assert(false) call which, if it would be reachable, does not leave the function, but abort.

Warning

test\src\unit-json_pointer.cpp(362,78): warning C4127: conditional expression is constant

seems to be a false positive. json::size_type is std::size_t whose size is implementation-defined, but at least 16 bit. unsigned long long is at least 64 bit. So

sizeof(typename json::size_type) < sizeof(unsigned long long)

is true very often, but not necessarily all the time.

@nlohmann nlohmann added the platform: visual studio related to MSVC label Jan 14, 2021
@nlohmann
Copy link
Owner

I'm not sure how to fix any of the warnings.

@Andreas-Schniertshauer
Copy link
Author

sizeof(typename json::size_type) < sizeof(unsigned long long)

can be solved in c++17 with

if constexpr (sizeof(typename json::size_type) < sizeof(unsigned long long))

@Andreas-Schniertshauer
Copy link
Author

The

default: // LCOV_EXCL_LINE

case does not return anything.

@t-b
Copy link
Contributor

t-b commented Jan 15, 2021

json::size_type is std::size_t whose size is implementation-defined, but at least 16 bit. unsigned long long is at least > 64 bit. So

sizeof(typename json::size_type) < sizeof(unsigned long long)
is true very often, but not necessarily all the time.

MSVC does not warn about the general case but about the case for the architecture being compiled.

@nlohmann
Copy link
Owner

can be solved in c++17 with

if constexpr (sizeof(typename json::size_type) < sizeof(unsigned long long))

The library targets C++11.

@nlohmann
Copy link
Owner

The

default: // LCOV_EXCL_LINE

case does not return anything.

That's true, but it also does not leave the function due to the assertion.

@gregmarr
Copy link
Contributor

If there were a return after the assert we'd probably get an unreachable code warning on it on other compilers.

This may help https://stackoverflow.com/questions/60802864/emulating-gccs-builtin-unreachable-in-visual-studio

@gregmarr
Copy link
Contributor

@nlohmann
Copy link
Owner

@gregmarr Thanks for the reference! A NODEFAULT macro could be a good addition to the library. Interestingly, we have several other places where we did put a return after an assertion, like

        default:                   // LCOV_EXCL_LINE
            JSON_ASSERT(false);    // LCOV_EXCL_LINE
            return 0;              // LCOV_EXCL_LINE

@gregmarr
Copy link
Contributor

If we already have places where we return after an assert and we're not getting errors there, then adding a return in this case seems like a reasonable fix.

@nlohmann
Copy link
Owner

The issue with the missing return value is fixed in the devlop branch: dd8cb2a#diff-a9407ccd45e5c9f004f9d81a18c381d0e5ecd782d5a91ec8f64614d3da6a7eaeR8397

I went through the code and did not find a similar issue. I would close this issue unless anyone has an idea what to do with C4127.

@nlohmann nlohmann added the solution: proposed fix a fix for the issue has been proposed and waits for confirmation label Jan 25, 2021
@nlohmann nlohmann added this to the Release 3.9.2 milestone Jan 25, 2021
@t-b
Copy link
Contributor

t-b commented Jan 25, 2021

I went through the code and did not find a similar issue. I would close this issue unless anyone has an idea what to do with C4127.

Globally disabling?

@nlohmann
Copy link
Owner

I'm not a big fan of that - especially since it seems not to be enabled by default or is it?

@gregmarr
Copy link
Contributor

Since the example shown is in a test file, I think it would be acceptable to have a pragma in that file to disable the warning. If it were in the main source, that would be a different story.

@nlohmann
Copy link
Owner

diff --git a/test/src/unit-json_pointer.cpp b/test/src/unit-json_pointer.cpp
index 14d8cd183..fc10c6ff5 100644
--- a/test/src/unit-json_pointer.cpp
+++ b/test/src/unit-json_pointer.cpp
@@ -358,6 +358,10 @@ TEST_CASE("JSON pointers")
                 CHECK_THROWS_WITH(j_const[jp] == 1, throw_msg.c_str());
             }
 
+#if defined(_MSC_VER)
+#pragma warning (push)
+#pragma warning (disable : 4127) // on some machines, the check below is not constant
+#endif
             if (sizeof(typename json::size_type) < sizeof(unsigned long long))
             {
                 auto size_type_max_uul = static_cast<unsigned long long>((std::numeric_limits<json::size_type>::max)());
@@ -371,6 +375,10 @@ TEST_CASE("JSON pointers")
                 CHECK_THROWS_WITH(j_const[jp] == 1, throw_msg.c_str());
             }
 
+#if defined(_MSC_VER)
+#pragma warning (pop)
+#endif
+
             CHECK_THROWS_AS(j.at("/one"_json_pointer) = 1, json::parse_error&);
             CHECK_THROWS_WITH(j.at("/one"_json_pointer) = 1,
                               "[json.exception.parse_error.109] parse error: array index 'one' is not a number");

@gregmarr @t-b @Andreas-Schniertshauer Is this what you'd have in mind?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: bug platform: visual studio related to MSVC release item: 🔨 further change solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants