mirror of
https://github.com/nlohmann/json.git
synced 2025-07-29 23:01:16 +03:00
Fix return value of get_ptr for unsigned integers (#4525)
* 🐛 fix return value of get_ptr for unsigned integers * 📝 update documentation
This commit is contained in:
@ -35,7 +35,35 @@ Constant.
|
||||
|
||||
!!! danger "Undefined behavior"
|
||||
|
||||
Writing data to the pointee of the result yields an undefined state.
|
||||
The pointer becomes invalid if the underlying JSON object changes.
|
||||
|
||||
Consider the following example code where the pointer `ptr` changes after the array is resized. As a result, reading or writing to `ptr` after the array change would be undefined behavior. The address of the first array element changes, because the underlying `std::vector` is resized after adding a fifth element.
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
int main()
|
||||
{
|
||||
json j = {1, 2, 3, 4};
|
||||
auto* ptr = j[0].get_ptr<std::int64_t*>();
|
||||
std::cout << "value at " << ptr << " is " << *ptr << std::endl;
|
||||
|
||||
j.push_back(5);
|
||||
|
||||
ptr = j[0].get_ptr<std::int64_t*>();
|
||||
std::cout << "value at " << ptr << " is " << *ptr << std::endl;
|
||||
}
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
value at 0x6000012fc1c8 is 1
|
||||
value at 0x6000029fc088 is 1
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
@ -54,6 +82,10 @@ Constant.
|
||||
--8<-- "examples/get_ptr.output"
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [get_ref()](get_ref.md) get a reference value
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 1.0.0.
|
||||
|
@ -40,7 +40,7 @@ Constant.
|
||||
|
||||
!!! danger "Undefined behavior"
|
||||
|
||||
Writing data to the referee of the result yields an undefined state.
|
||||
The reference becomes invalid if the underlying JSON object changes.
|
||||
|
||||
## Examples
|
||||
|
||||
@ -58,6 +58,10 @@ Constant.
|
||||
--8<-- "examples/get_ref.output"
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [get_ptr()](get_ptr.md) get a pointer value
|
||||
|
||||
## Version history
|
||||
|
||||
- Added in version 1.1.0.
|
||||
|
@ -1463,13 +1463,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// get a pointer to the value (integer number)
|
||||
number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
|
||||
{
|
||||
return is_number_integer() ? &m_data.m_value.number_integer : nullptr;
|
||||
return m_data.m_type == value_t::number_integer ? &m_data.m_value.number_integer : nullptr;
|
||||
}
|
||||
|
||||
/// get a pointer to the value (integer number)
|
||||
constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
|
||||
{
|
||||
return is_number_integer() ? &m_data.m_value.number_integer : nullptr;
|
||||
return m_data.m_type == value_t::number_integer ? &m_data.m_value.number_integer : nullptr;
|
||||
}
|
||||
|
||||
/// get a pointer to the value (unsigned number)
|
||||
|
@ -20962,13 +20962,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/// get a pointer to the value (integer number)
|
||||
number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
|
||||
{
|
||||
return is_number_integer() ? &m_data.m_value.number_integer : nullptr;
|
||||
return m_data.m_type == value_t::number_integer ? &m_data.m_value.number_integer : nullptr;
|
||||
}
|
||||
|
||||
/// get a pointer to the value (integer number)
|
||||
constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /*unused*/) const noexcept
|
||||
{
|
||||
return is_number_integer() ? &m_data.m_value.number_integer : nullptr;
|
||||
return m_data.m_type == value_t::number_integer ? &m_data.m_value.number_integer : nullptr;
|
||||
}
|
||||
|
||||
/// get a pointer to the value (unsigned number)
|
||||
|
@ -326,7 +326,7 @@ TEST_CASE("pointer access")
|
||||
CHECK(value.get_ptr<json::array_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::string_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::boolean_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_integer_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<json::number_integer_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::number_unsigned_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<json::number_float_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<json::binary_t*>() == nullptr);
|
||||
@ -355,7 +355,7 @@ TEST_CASE("pointer access")
|
||||
CHECK(value.get_ptr<const json::array_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::string_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::boolean_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_integer_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<const json::number_integer_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::number_unsigned_t*>() != nullptr);
|
||||
CHECK(value.get_ptr<const json::number_float_t*>() == nullptr);
|
||||
CHECK(value.get_ptr<const json::binary_t*>() == nullptr);
|
||||
|
@ -215,8 +215,8 @@ TEST_CASE("reference access")
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
||||
CHECK_THROWS_WITH_AS(value.get_ref<json::boolean_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
||||
//CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(),
|
||||
// "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_integer_t&>(),
|
||||
"[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
||||
CHECK_NOTHROW(value.get_ref<json::number_unsigned_t&>());
|
||||
CHECK_THROWS_WITH_AS(value.get_ref<json::number_float_t&>(), "[json.exception.type_error.303] incompatible ReferenceType for get_ref, actual type is number", json::type_error&);
|
||||
}
|
||||
|
Reference in New Issue
Block a user