Casting 0-1 int r-value to bool - c++

I have an expression which returns 0 or 1 integer as a temporary value. The value is probably already in a register and I would like to return it as a bool from an inlined function.
Is there an ordinary way to do this? I believe (bool) and static_cast<bool> inject additional test and set instructions. And this is too much for me, while the case is about a performance critical part of memory manager.

Just return it. Any value, different from 0 is true and 0 is false in c++.
Just return the int from your inline function (which returns bool).

Assuming your integer expression is foo, then use !!foo to get the bool value.

What are you doing with the return value? If you are using it
immediately in condition, the compiler will probably generate
exactly the same code, regardless of whether the type is bool
or not. There will be a simple comparison with 0. If you are
assigning it to a bool variable, the compiler will generally
generate an extra instruction, to ensure that the binary value
is either 0 or 1 (and not some other value). But what is
the expression, so that you can be sure that it is either 0 or
1? If it is something like x & 1, a good compiler will
recognize this, and will optimize out the extra instruction.
EDIT:
I might add that I am assuming inlining and optimization.
If performance is an issue, those are the first two steps
you should take.

When I come across such performance warnings in cppcheck, I usually use the most elegant approach for this (at least in my opinion ;) ):
return yourInt != 0;
This sticks with the assumption that all values different from 0 are considered true.

how about
return rtVal;
just return the integer will return true if it isn't 0

from c++ 2012 standard (ISO/IEC N3337):
4.12 Boolean conversions
A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a
prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false;
any other value is converted to true. A prvalue of type std::nullptr_t can be converted to a prvalue of
type bool; the resulting value is false.
So just return it?!

Related

How are bools stored in C++? [duplicate]

As already discussed in the docs, a bool data type occupies at least a byte of memory. A similar question was asked on SO before (How a bool type variable is stored in memory? (C++)), but this discussion and the documentation only seem to discuss the amount of space occupied by a boolean data type, not what actually happens in memory when I do this:
bool b = true;
So what does actually happen in memory? What happens to the 7 bits that are not used in storing this information? Does the standard prescribe behavior for this?
Are they undefined? Or did someone at C++ headquarters just do this:
enum bool : char
{
false = 0,
true = 1
};
Standard states that bool values behave as integral types, yet it doesn't specify their concrete representation in memory:
"Values of type bool are either true or false. As described below, bool values behave as integral types. Values of type bool participate in integral promotions" ~ C++03 3.9.1 §6
"A synonym for integral type is integer type. The representations of integral types shall define values by use of a pure binary numeration system" ~ C++03 3.9.1 §7
Yet it defines the integral promotion from bool to int:
"An rvalue of type bool can be converted to an rvalue of type int, with false becoming zero and true becoming one. These conversions are called integral promotions." ~ C++03 4.5 §4-5
as well as conversion from other types to bool:
"A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true." ~ C++03 4.12 §1
The standard doesn't mandate anything for the binary representation of bools; it just says that, when converting to other integral types, a true bool will become 1 and a false bool will become 0.
This of course suggests an implementation similar in spirit to the one you said, where such conversions would become essentially no-ops or plain integer widening (but remember that bool is mandated to be a primitive type, not an enumeration type).
You can test things like this by copying the memory, ignoring which type it is. This program reads the raw memory value of test_bool and puts it into test_int so that you may print it.
int test_int = 0;
bool test_bool;
test_bool = true;
memcpy (&test_int, &test_bool, sizeof(bool));
printf ("True value is: %d\n", test_int);
test_bool = false;
memcpy (&test_int, &test_bool, sizeof(bool));
printf ("False value is: %d\n", test_int);
For me, this program gives:
True value is: 1
False value is: 0
I didn't program in C++ since a couple of months but AFAIR the rule is the following:
0 - false;
any value different than 0 - true; (by default it's 1 but AFAIR if you convert it from other integer value, ex. 2 will be also treated as true).
Thus you can say that C++ in some way waste memory (others too) as it could use one bit only but it's simpler to make compiler then.
In C++ you can also define bit fields (bit fields in wikipedia) but it's not used often.

What does an exclamation mark in array index do?

While perusing through my organization's source repository I came across this little gem:
RawParameterStorage[!ParameterWorkingIdx][ParameterDataOffset] = ...
Is this valid code? (It compiles) What does the exclamation mark here do?
An invert ~ operator might make sense, since it's commonly confused with the not ! operator in boolean expressions. However, it doesn't seem to make logical sense to impose the not ! operator on an array index. Any Thoughts?
!ParameterWorkingIdx Means ParameterWorkingIdx is 0, If it is, !ParameterWorkingIdx evaluates as true which might be implicitly converted to the indexer type (For example, 1 for integer indexer as in an array), otherwise, it evaluates as false.
If ParameterWorkingIdx == 0 then [!ParameterWorkingIdx] == [1].
If ParameterWorkingIdx != 0 then [!ParameterWorkingIdx] == [0].
It also depends on other stuff like:
The type of ParameterWorkingIdx.
overloading of ! operator by the type of ParameterWorkingIdx.
indexer overloading by the type of RawParameterStorage.
etc...
Taking a bit of a guess here, but that looks like a double-buffer pattern. ParameterWorkingIdx would flip-flop between 0 and 1 (probably with ParameterWorkingIdx = !ParameterWorkingIdx;).
Then, at any time, RawParameterStorage[ParameterWorkingIdx] would be the current buffer, and RawParameterStorage[!ParameterWorkingIdx] would be the previous buffer.
it doesn't seem to make logical sense to impose the not ! operator on an array index
It might: all it does here is convert zero to one, and any other number to zero.
We can infer from this code that RawParameterStorage probably has two elements at the top level.
P. S. Here, I assume that RawParameterStorage is an array (as you say it is). Furthermore, I assume that ParameterWorkingIdx is an integer (as its name implies). If, for example, either is a class with overloaded operators than the semantics could be completely different.
Is this valid code?
Yes it is. Suppose ParameterWorkingIdx to be an int, for !ParameterWorkingIdx, when used with operators !, it'll be contextually convertible to bool,
The value zero (for integral, floating-point, and unscoped enumeration) and the null pointer and the null pointer-to-member values become false. All other values become true.
Then integral promoted to be used as the array index.
the type bool can be converted to int with the value false becoming ​0​ and true becoming 1.
So !ParameterWorkingIdx is equivalent with ParameterWorkingIdx == 0 ? 1 : 0, which is much more clear IMO.

using Boolean to represent integers

In c++, bool is used to represent Boolean. that is it holds true or false. But in some case we can use bool to represent integers also.
what is the meaning of bool a=5; in c++?
"what is the meaning of bool a=5; in c++?"
It's actually equivalent to writing
bool a = (5 != 0);
"But in some case we can use bool to represent integers also."
Not really. The bool value only represents whether the integer used to initialize it was zero (-> false) or not (-> true).
The other way round (as mentioned in #Daniel Frey's comment) false will be converted back to an integer 0, and true will become 1.
So the original integer value's (or any other expression results like pointers, besides nullptr, or double values not exactly representing 0.0) will be lost.
Conclusion
As mentioned in LRiO's answer, it's not possible to store information other than false or true in a bool variable.
There are guaranteed rules of conversion though (citation from cppreference.com):
The safe bool problem
Until the introduction of explicit conversion functions in C++11, designing a class that should be usable in boolean contexts (e.g. if(obj) { ... }) presented a problem: given a user-defined conversion function, such as T::operator bool() const;, the implicit conversion sequence allowed one additional standard conversion sequence after that function call, which means the resultant bool could be converted to int, allowing such code as obj << 1; or int i = obj;.
One early solution for this can be seen in std::basic_ios, which defines operator! and operator void* (until C++11), so that the code such as if(std::cin) {...} compiles because void* is convertible to bool, but int n = std::cout; does not compile because void* is not convertible to int. This still allows nonsense code such as delete std::cout; to compile, and many pre-C++11 third party libraries were designed with a more elaborate solution, known as the Safe Bool idiom.
No, we can't.
It's just that there's an implicit conversion from integer to boolean.
Zero becomes false; anything else becomes true.
In fact this declaration
bool a=5;
is equivalent to
bool a=true;
except that in the first declaration 5 as it is not equal to zero is implicitly converted to true.
From the C++ Standard (4.12 Boolean conversions )
1 A prvalue of arithmetic, unscoped enumeration, pointer, or pointer
to member type can be converted to a prvalue of type bool. A zero
value, null pointer value, or null member pointer value is converted
to false; any other value is converted to true. For
direct-initialization (8.5), a prvalue of type std::nullptr_t can be
converted to a prvalue of type bool; the resulting value is false.
One more funny example
bool a = new int;
Of course it does not mean that we may use bool to represent pointers. Simply if the allocation is successfull then the returned poimter is not equal to zero and implicitly converted to true according to the quote I showed.
Take into account that till now some compilers have a bug and compile this code successfully
bool a = nullptr;
Though according to the same quote a valid declaration will look like
bool a( nullptr );
And, basically, I would opine that bool b=5 is "just plain wrong."
Both C and C++ have a comparatively weak system of typing. Nevertheless, I'm of the opinion that this should have produced a compile error ... and, if not, certainly a rejected code review, because it is (IMHO) more likely to be an unintentional mistake, than to be intention.
You should examine the code to determine whether b is or is not "really" being treated as a bool value. Barring some "magic bit-twiddling purpose" (which C/C++ programs sometimes are called-upon to do ...), this is probably a typo or a bug.
Vlad's response (below) shows what the standard says will happen if you do this, but I suggest that, "since it does not make human-sense to do this, it's probably an error and should be treated accordingly by the team.
A "(typecast)?" Maybe. A data-type mismatch such as this? Nyet.

How is a bool represented in memory?

As already discussed in the docs, a bool data type occupies at least a byte of memory. A similar question was asked on SO before (How a bool type variable is stored in memory? (C++)), but this discussion and the documentation only seem to discuss the amount of space occupied by a boolean data type, not what actually happens in memory when I do this:
bool b = true;
So what does actually happen in memory? What happens to the 7 bits that are not used in storing this information? Does the standard prescribe behavior for this?
Are they undefined? Or did someone at C++ headquarters just do this:
enum bool : char
{
false = 0,
true = 1
};
Standard states that bool values behave as integral types, yet it doesn't specify their concrete representation in memory:
"Values of type bool are either true or false. As described below, bool values behave as integral types. Values of type bool participate in integral promotions" ~ C++03 3.9.1 §6
"A synonym for integral type is integer type. The representations of integral types shall define values by use of a pure binary numeration system" ~ C++03 3.9.1 §7
Yet it defines the integral promotion from bool to int:
"An rvalue of type bool can be converted to an rvalue of type int, with false becoming zero and true becoming one. These conversions are called integral promotions." ~ C++03 4.5 §4-5
as well as conversion from other types to bool:
"A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true." ~ C++03 4.12 §1
The standard doesn't mandate anything for the binary representation of bools; it just says that, when converting to other integral types, a true bool will become 1 and a false bool will become 0.
This of course suggests an implementation similar in spirit to the one you said, where such conversions would become essentially no-ops or plain integer widening (but remember that bool is mandated to be a primitive type, not an enumeration type).
You can test things like this by copying the memory, ignoring which type it is. This program reads the raw memory value of test_bool and puts it into test_int so that you may print it.
int test_int = 0;
bool test_bool;
test_bool = true;
memcpy (&test_int, &test_bool, sizeof(bool));
printf ("True value is: %d\n", test_int);
test_bool = false;
memcpy (&test_int, &test_bool, sizeof(bool));
printf ("False value is: %d\n", test_int);
For me, this program gives:
True value is: 1
False value is: 0
I didn't program in C++ since a couple of months but AFAIR the rule is the following:
0 - false;
any value different than 0 - true; (by default it's 1 but AFAIR if you convert it from other integer value, ex. 2 will be also treated as true).
Thus you can say that C++ in some way waste memory (others too) as it could use one bit only but it's simpler to make compiler then.
In C++ you can also define bit fields (bit fields in wikipedia) but it's not used often.

Can I assume (bool)true == (int)1 for any C++ compiler?

Can I assume (bool)true == (int)1 for any C++ compiler ?
Yes. The casts are redundant. In your expression:
true == 1
Integral promotion applies and the bool value will be promoted to an int and this promotion must yield 1.
Reference: 4.7 [conv.integral] / 4: If the source type is bool... true is converted to one.
Charles Bailey's answer is correct. The exact wording from the C++ standard is (§4.7/4): "If the source type is bool, the value false is converted to zero and the value true is converted to one."
Edit: I see he's added the reference as well -- I'll delete this shortly, if I don't get distracted and forget...
Edit2: Then again, it is probably worth noting that while the Boolean values themselves always convert to zero or one, a number of functions (especially from the C standard library) return values that are "basically Boolean", but represented as ints that are normally only required to be zero to indicate false or non-zero to indicate true. For example, the is* functions in <ctype.h> only require zero or non-zero, not necessarily zero or one.
If you cast that to bool, zero will convert to false, and non-zero to true (as you'd expect).
According to the standard, you should be safe with that assumption. The C++ bool type has two values - true and false with corresponding values 1 and 0.
The thing to watch about for is mixing bool expressions and variables with BOOL expression and variables. The latter is defined as FALSE = 0 and TRUE != FALSE, which quite often in practice means that any value different from 0 is considered TRUE.
A lot of modern compilers will actually issue a warning for any code that implicitly tries to cast from BOOL to bool if the BOOL value is different than 0 or 1.
I've found different compilers return different results on true. I've also found that one is almost always better off comparing a bool to a bool instead of an int. Those ints tend to change value over time as your program evolves and if you assume true as 1, you can get bitten by an unrelated change elsewhere in your code.
If I write the code:
int a=true;
cout<<a;
The output will be:
1
So yes, you can assume (bool)true==(int)1