nlohmann / json

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

INT64_MIN/MAX not defined for newer g++ #3722

Closed billpriest closed 1 year ago

billpriest commented 1 year ago

Description

While cross compiling for arm w/ newer versions of g++ INT64_MAX, INT64_MIN, UINT64, INT32_MIN, INT32_MAX, UINT32_MAX aren't defined. I found the following: / The ISO C99 standard specifies that in C++ implementations these macros should only be defined if explicitly requested. /

if !defined cplusplus || defined STDC_LIMIT_MACROS

Rather than adding the #define to make this work I created a patch that uses the std::numeric_limits::max() I guess a "compatibility" include file could be created to work around this issue; but it wasn't obvious to me how to do this.

After applying the patch I ran all the tests and they all passed. int64_min_max.patch.txt

Reproduction steps

git clone https://github.com/nlohmann/json.git cd json git checkout v3.11.2 mkdir build cd build cmake -DCMAKE_TOOLCHAIN_FILE=../../aarch64.cmake -DCMAKE_INSTALL_PREFIX=/opt/nxpimx8/usr/local .. make

Expected vs. actual results

See compiler errors below.

Minimal code example

No response

Error messages

json/tests/src/unit-to_chars.cpp:466:23: error: 'INT64_MIN' was not declared in this scope
  466 |         check_integer(INT64_MIN, "-9223372036854775808");
      |                       ^~~~~~~~~
/home/priestwilliaml/newbuild/build/json/tests/src/unit-to_chars.cpp:467:23: error: 'INT64_MAX' was not declared in this scope
  467 |         check_integer(INT64_MAX, "9223372036854775807");
      |                       ^~~~~~~~~

json/tests/src/unit-cbor.cpp: In function 'void _DOCTEST_ANON_FUNC_7()':
/home/priestwilliaml/newbuild/build/json/tests/src/unit-cbor.cpp:176:39: error: 'INT64_MIN' was not declared in this scope
  176 |                     numbers.push_back(INT64_MIN);
      |                                       ^~~~~~~~~

json/tests/src/unit-msgpack.cpp:511:39: error: 'INT64_MIN' was not declared in this scope
  511 |                     numbers.push_back(INT64_MIN);
      |                                       ^~~~~~~~~

json/tests/src/unit-regression1.cpp: In function 'void _DOCTEST_ANON_FUNC_7()':
/home/priestwilliaml/newbuild/build/json/tests/src/unit-regression1.cpp:880:51: error: 'INT64_MIN' was not declared in this scope
  880 |         CHECK(j1.get<json::number_integer_t>() == INT64_MIN);
      |                                                   ^~~~~~~~~

Compiler and operating system

linux g++ 11.2.0 crosscompiling for ARM 64

Library version

v3.11.2 from github

Validation

falbrechtskirchinger commented 1 year ago

We should be using std::numeric_limits anyway.

falbrechtskirchinger commented 1 year ago

INT64_MIN/MAX not defined for newer g++

The problem is usually older compilers (or standard libraries, technically). C++11 (and C11) removed the need for __STDC_LIMIT_MACROS.

#if (!defined __cplusplus || __cplusplus >= 201103L \
     || defined __STDC_LIMIT_MACROS)

Even after replacing these limit macros, we still depend on SIZE_MAX for conditional code and can't easily replace those uses with std::numeric_limits because of enabled compiler warnings.

I wonder why your compiler doesn't seem to complain about that? (SIZE_MAX is defined within the same conditional block in my header files.)