Reputation: 70000
In its simplest form, below is a pseudo code of the problem:
enum E { VALUE = -1; }
uint32_t value = VALUE; // signed to unsigned conversion without typecasting
SQLiteDB.INSERT(<table containing `value`>);
SQLiteDB.SELECT(<same table as above>);
In the DB, I see that the value
is stored as 4294967295
(i.e. 0xFFFFFFFF
) which is correct. But when the value is read from the DB, it is truncated as 2147483647
(0x7FFFFFFF
) which is appx half of the original value.
Why is that? How to solve this problem?
Update: As informed above, the value 0xFFFFFFFF is visible in SQLite properly, but when read in the uint32_t
back, it's truncated. Possibly is it a data loss?
Below is an image seen with SQLiteBrowser on the actual data.
Related but not duplicate:
Upvotes: 1
Views: 677
Reputation: 70000
Found the issue.
I am using a library code to read the DB tables. Which gets the values in form of string properly. Further std::stoi()
is used for converting to the desired uint32_t
.
Now 4294967295
is too big of an integer for an std::stoi()
. In fact in Ubuntu 64-bit machine, it throws an exception. However in Windows, somehow it truncates by resetting the sign bit to 0 and hence it becomes 2147483647
. May be this is a consistent undefined behaviour. :-)
Instead of std::stoi()
, if we use std::stol()
or ::strtoul()
, then that resolves the problem and the value is read correctly as 4294967295
to a uint32_t
variable.
Upvotes: 2