Unexpected Integer Conversion of JSON Values on ARM64
Dontla opened this issue · 1 comments
Description
I encountered an issue with the nlohmann/json library where integer values parsed from a JSON object are not correctly converted when using the get(), get(), and get() methods on ARM64 architecture. This behavior results in incorrect data retrieval from a JSON object that otherwise appears to contain the correct values when outputted as raw JSON or accessed directly without type conversion. This issue may represent a bug in type handling or integer conversion specific to ARM64 environments.
Reproduction steps
- Parse a JSON object containing an integer value using nlohmann/json.
- Retrieve the integer using get(), get(), and get().
- Print the retrieved values to the console.
My raw json:
{
"config": {
"port": "/dev/ttyTHS0",
"baudRate": 9600,
"deviceAddress": 1,
"deviceType": "AlarmCircuitMaster",
"controlType": "start"
},
"commands": {
"alarmType": "yellow"
}
}
My C++ code:
` std::cout << "Received JSON for POST request: " << std::endl;
std::cout << j.dump(4) << std::endl;
std::cout << "Is baudRate a number? " << j["config"]["baudRate"].is_number() << std::endl;
std::cout << "baudRate as int: " << j.at("config").at("baudRate").get<int>() << std::endl;
std::cout << "baudRate as int: " << j["config"]["baudRate"].get<int>() << std::endl;
std::cout << "baudRate as long: " << j["config"]["baudRate"].get<long>() << std::endl;
std::cout << "baudRate as long: " << j.at("config").at("baudRate").get<long>() << std::endl;
std::cout << "baudRate as unsigned int: " << j["config"]["baudRate"].get<unsigned int>() << std::endl;
std::cout << "baudRate as unsigned int: " << j.at("config").at("baudRate").get<unsigned int>() << std::endl;
std::cout << "Raw baudRate value: " << j["config"]["baudRate"] << std::endl;
std::cout << "baw baudRate value: " << j.at("config").at("baudRate") << std::endl;
`
Expected vs. actual results
Expected: The integer values retrieved from the JSON object should match the values present in the JSON.
Actual: The retrieved values are consistently incorrect (e.g., expecting 9600 but receiving 2580) despite the JSON object showing correct values when printed directly.
Expected results:
Received JSON for POST request:
{
"commands": {
"alarmType": "yellow"
},
"config": {
"baudRate": 9600,
"controlType": "start",
"deviceAddress": 1,
"deviceType": "AlarmCircuitMaster",
"port": "/dev/ttyTHS0"
}
}
Is baudRate a number? 1
baudRate as int: 9600
baudRate as int: 9600
baudRate as long: 9600
baudRate as long: 9600
baudRate as unsigned int: 9600
baudRate as unsigned int: 9600
Raw baudRate value: 9600
baw baudRate value: 9600
Actual results:
Received JSON for POST request:
{
"commands": {
"alarmType": "yellow"
},
"config": {
"baudRate": 9600,
"controlType": "start",
"deviceAddress": 1,
"deviceType": "AlarmCircuitMaster",
"port": "/dev/ttyTHS0"
}
}
Is baudRate a number? 1
baudRate as int: 2580
baudRate as int: 2580
baudRate as long: 2580
baudRate as long: 2580
baudRate as unsigned int: 2580
baudRate as unsigned int: 2580
Raw baudRate value: 9600
baw baudRate value: 9600
Minimal code example
#include <iostream>
#include <nlohmann/json.hpp>
int main() {
std::string jsonData = R"({"config": {"baudRate": 9600}})";
auto json = nlohmann::json::parse(jsonData);
std::cout << "Expected Baud Rate: 9600" << std::endl;
std::cout << "Actual Baud Rate as int: " << json["config"]["baudRate"].get<int>() << std::endl;
return 0;
}
Error messages
No compilation errors or exceptions are thrown. The output is incorrect as described in the "Actual Results".
Compiler and operating system
OS: Ubuntu 20.04 ARM64, Compiler: g++9.4.0
Library version
Version 3.11.3 of the nlohmann/json library, obtained directly from the GitHub repository.
Validation
- The bug also occurs if the latest version from the
develop
branch is used. - I can successfully compile and run the unit tests.
I found the problem; it was in my C++ code. The code executed std::cout << std::hex << std::uppercase << std::setw(2) << std::setfill('0') << static_cast<int>(tbuf[i]) << " ";
, which set the global std::cout
output to hexadecimal format. That's why the baud rate of 9600 was printed as 2580.