I've found a difference in the value stored in a bool variable (btw Visual-C++ and clang++), in the case where the stored value is neither true nor false (if it was corrupted somehow), and I'm not sure if it's a Visual-C++ bug or if it's just UB I should ignore.
Take the following sample:
#include <cstdint>
#include <iostream>
#include <string>
#include <limits>
bool inLimits(bool const v)
{
return (static_cast<std::int32_t>(v) >= static_cast<std::int32_t>(std::numeric_limits<bool>::min()) && static_cast<std::int32_t>(v) <= static_cast<std::int32_t>(std::numeric_limits<bool>::max()));
}
int main()
{
bool b{ false };
bool const* const pb = reinterpret_cast<bool const*>(&b);
std::uint8_t * const pi = reinterpret_cast<std::uint8_t*>(&b);
std::cout << "b: " << b << " pb: " << (*pb) << " pi: " << std::to_string(*pi) << std::endl;
std::cout << "b is " << (inLimits(b) ? "" : "not ") << "in numeric limits for a bool" << std::endl;
*pi = 3; // Simulate a bad cast during boolean creation
bool const b2{ b };
bool const b3{ *pb };
std::cout << "b: " << b << " pb: " << (*pb) << " pi: " << std::to_string(*pi) << std::endl;
std::cout << "b2: " << b2 << " b3: " << b3 << std::endl;
std::cout << "b is " << (inLimits(b) ? "" : "not ") << "in numeric limits for a bool" << std::endl;
std::cout << "b2 is " << (inLimits(b2) ? "" : "not ") << "in numeric limits for a bool" << std::endl;
std::cout << "b3 is " << (inLimits(b3) ? "" : "not ") << "in numeric limits for a bool" << std::endl;
return 0;
}
This is the output of Visual-C++
b: 0 pb: 0 pi: 0
b is in numeric limits for a bool
b: 3 pb: 3 pi: 3
b2: 3 b3: 3
b is not in numeric limits for a bool
b2 is not in numeric limits for a bool
b3 is not in numeric limits for a bool
and this is the output of clang++
b: 0 pb: 0 pi: 0
b is in numeric limits for a bool
b: 1 pb: 1 pi: 3
b2: 1 b3: 1
b is in numeric limits for a bool
b2 is in numeric limits for a bool
b3 is in numeric limits for a bool
It looks like there is a limits check in clang++ when constructing a new boolean by value, as well as when it is used with stream operator.
Should I just ignore this, or is it a bug that only Visual-C++ has? Thanks!
Edit: For those who did not understand the purpose of the sample, it was just a showcase to "simulate" a memory corruption or a bug in another part of the code that caused a boolean value to be initialized with something else than true or false, whatever the binary representation of a bool.
(I was wondering if I have to protect my code from improper usage somewhere else using an assert for example, but only if this behavior is not UB)
Second edit: Added numeric_limits code.