Output of boost::lexical_cast
with a bool
variable as input is expected to be a 0
or 1
value. But I get different value instead.
It's not something which happen normally. Let's take a look at example code I've wrote:
#include <string>
#include <boost/lexical_cast.hpp>
int main()
{
bool alfa = true; // Doesn't metter whether alfa is initialized at definition or not
char beta = 71; // An integer value. Different values don't make any differences.
memcpy(&alfa, &beta, sizeof(alfa));
printf("%s\n", boost::lexical_cast<std::string>(alfa).c_str());
}
From this code, I've got "w"
(ASCII code of w is 71) as output! But I expected it to be a 0
or 1
value.
The problem is just the value that bool
variable will cast into. The bool
variable in the given example is already considered true.
What causes problem is imagine I want to convert back the converted value. That's where it throws exception because for example "w" character can't be converted to bool
. But if the output was 0
or 1
, re-conversion would be possible.
std::string converted_value = boost::lexical_cast<std::string>(alfa);
bool reconverted_value = boost::lexical_cast<bool>(converted_value ); // In this line, boost::bad_lexical_cast will be thrown
I was wondering whether the output is right or this is a bug in boost::lexical_cast
?
Also when I was trying to do the same thing and cast the variable to int
, I faced boost::bad_lexical_cast
exception.
My boost version: 1.58
Live sample
The C++ standard does not specify how a Boolean is stored in memory, only that there are two possible values: true
and false
. Now, on your machine, I presume these are stored, respectively, as 1
and 0
. The compiler is allowed to make assumptions, and in particular it's allowed to assume that these are going to be the only two values stored in a Boolean.
Thus, when boost::lexical_cast
sees a Boolean, it runs code that probably looks something like this (after optimization)
// Gross oversimplification
std::string lexical_cast(bool value) {
char res = '0' + (int)value;
return std::string(1, res);
}
If value
is 0
or 1
, this works fine and does what you want. However, you put a 71
into it. So we add the ASCII code of '0'
(48
) to 71
and get 119
, the ASCII code of 'w'
.
Now, I'm not a C++ standard expert, but I would guess that storing a non-standard value into a Boolean with memcpy
is undefined behavior. At the very least, your code is non-portable. Perhaps someone more versed in the standard can fill in the holes in my knowledge as far as that's concerned.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With