Shouldn't it be ok to use static_cast to convert int to bool as it converts reverse of implicit conversion but i still get a warning?
Example:
MSVC++ 8
bool bit = static_cast<bool>(100);
Just because the conversion a => b is implicit doesn’t say anything about the viability of the reverse, b => a.
In your case, you shouldn’t cast at all. Just do the obvious thing: compare:
bool result = int_value != 0;
This is the only logically correct way of converting an int to bool and it makes the code much more readable (because it makes the assumptions explicit).
The same applies for the reverse, by the way. Converting implicitly from bool to int is just lazy. Make the mapping explicit:
int result = condition ? 1 : 0;
That's between you and your compiler, but Microsoft thinks you should write:
i != 0
in preference to either:
(bool)i
or
static_cast<bool>(i)
Possible reasons for preferring it include:
this conversion doesn't act like other narrowing conversions, that take a modulus,
the implict conversions to bool are also a bit controversial: plenty of people prefer to do if (buf != NULL) or if (buf != 0) in preference to if (buf) after a call to malloc,
the comparison is both shorter and clearer.
I'm not sure why it happens when you explicitly cast it (i think it was a performance warning?), but I usually use code like this to avoid any warnings:
int i;
bool b = (0!=i);
This never gives warnings.
I do as someone already posted:
bool result = int_value != 0;
It's the easier way imo and the it's more intuitive than trying to cast the integer to bool.
Related
How does one convert from one integer type to another safely and with setting off alarm bells in compilers and static analysis tools?
Different compilers will warn for something like:
int i = get_int();
size_t s = i;
for loss of signedness or
size_t s = get_size();
int i = s;
for narrowing.
casting can remove the warnings but don't solve the safety issue.
Is there a proper way of doing this?
You can try boost::numeric_cast<>.
boost numeric_cast returns the result of converting a value of type Source to a value of type Target. If out-of-range is detected, an exception is thrown (see bad_numeric_cast, negative_overflow and positive_overflow ).
How does one convert from one integer type to another safely and with setting off alarm bells in compilers and static analysis tools?
Control when conversion is needed. As able, only convert when there is no value change. Sometimes, then one must step back and code at a higher level. IOWs, was a lossy conversion needed or can code be re-worked to avoid conversion loss?
It is not hard to add an if(). The test just needs to be carefully formed.
Example where size_t n and int len need a compare. Note that positive values of int may exceed that of size_t - or visa-versa or the same. Note in this case, the conversion of int to unsigned only happens with non-negative values - thus no value change.
int len = snprintf(buf, n, ...);
if (len < 0 || (unsigned)len >= n) {
// Handle_error();
}
unsigned to int example when it is known that the unsigned value at this point of code is less than or equal to INT_MAX.
unsigned n = ...
int i = n & INT_MAX;
Good analysis tools see that n & INT_MAX always converts into int without loss.
There is no built-in safe narrowing conversion between int types in c++ and STL. You could implement it yourself using as an example Microsoft GSL.
Theoretically, if you want perfect safety, you shouldn't be mixing types like this at all. (And you definitely shouldn't be using explicit casts to silence warnings, as you know.) If you've got values of type size_t, it's best to always carry them around in variables of type size_t.
There is one case where I do sometimes decide I can accept less than 100.000% perfect type safety, and that is when I assign sizeof's return value, which is a size_t, to an int. For any machine I am ever going to use, the only time this conversion might lose information is when sizeof returns a value greater than 2147483647. But I am content to assume that no single object in any of my programs will ever be that big. (In particular, I will unhesitatingly write things like printf("sizeof(int) = %d\n", (int)sizeof(int)), explicit cast and all. There is no possible way that the size of a type like int will not fit in an int!)
[Footnote: Yes, it's true, on a 16-bit machine the assumption is the rather less satisfying threshold that sizeof won't return a value greater than 32767. It's more likely that a single object might have a size like that, but probably not in a program that's running on a 16-bitter.]
I have to maintain a large codebase of rather old Visual C++ source. I found code like:
bIsOk = !!m_ptr->isOpen(some Parameters)
The datatype of bIsOk is bool, isOpen(..) returns BOOL (defined as int)
The engineer told me that was said to be the most efficient way to get from BOOL to bool.
Was that correct? Is it still nowadays? 2019?
The reason for the !! is not efficiency - any decent compiler will compile it to the exact same thing as any other non-bonkers way of converting, including just relying on an implicit conversion - but that it suppresses a compiler warning about an implicit narrowing to a bool present in older versions of Microsoft's compiler in VisualStudio but was removed in VS2017.
bVariable = !!iVariable vs. bVariable = (iVariable != 0)
You should worry about readability first, let compiler produce efficient code.
If you have an assignment like that just assign one to another:
bVariable = iVariable;
as int to bool conversion is well defined and should be readable by any C++ programmer.
if you need to convert variable or expression use proper C++ way - static_cast
template<class T>
void foobar( T t );
foobar( static_cast<bool>( iVariable ) ); // explicitly let reader know that you changing type
I'm assuming you are referring to the Win32 type BOOL, which is a typedef for int for historic C compatibility.
!! normalizes a boolean, changing any non-zero (i.e. TRUE) value into 1/true. As for efficiency, that's difficult to reason about. The other methods for normalizing a boolean (x || 0, x && 1, (x != 0), etc.) should all be optimized to the same thing by any decent compiler.
That is, if the normalization is explicitly needed, which it shouldn't be unless the intent is to suppress a compiler warning.
So, in C++ (and C) you can just implicitly convert to bool (_Bool). Thus, you can simply write
bIsOk = m_ptr->isOpen(some Parameters)
The operators !! however make it clear that there is a conversion. They are equivalent to a standard cast (bool)m_ptr->isOpen(some Parameters) or to m_ptr->isOpen(some Parameters)!=0. The only advantage of !! is that it is less code than a cast.
All of those produce exactly the same assembly: see here
Given that you are assigning to a bool, such a conversion is already done implicitly by the compiler, so the "double bang" is useless here.
It can still be useful to "normalize" a BOOL (or similar stuff) if you need to get a bool from a BOOL inside an expression. On modern compilers I expect it to generate the same code as != 0, the only advantage is that it's less to type (especially given that the unary ! has high precedence, while with != you may need to add parentheses).
I've got just a simple question about bitwise AND in C++.
I'm using it for single bits (a&8, a&4, a&2, a&1, etc.) and I want to get bool value as a return (if there's 1 on the position).
I may divide it by a number (like (a&8)/8), but it dosn't really look nice in my code (especially, that I'm using arrays and long names of variables).
Is there any other, better, way to code it?
Thanks in advance.
The best way is to convert the expression to a boolean value. This improves readability:
bool result;
result = 0 != (a & 8);
The comparison with 0 might be unnecessary since the compiled code will write true or false in the variable b. But this avoids a warning like:
warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)
The order or the comparison argument might be reversed if you don't like Yoda speech. It's a style that can help avoid accidental assignments in C programming language.
If you want to be explicit, compare with 0:
const bool maskSet = (a & 8) != 0;
That's the cleanest way I know of. Dividing is much stranger, since that still leaves the conversion from an integer to a boolean implicit. The comparison operator makes it explicit.
In source files which I am using in my project, there is a comparison between ssize_t and size_t variables:
ssize_t sst;
size_t st;
if(sst == st){...}
I would like to get rid of the warning:
warning: comparison between signed and unsigned integer expressions
But I am not sure, which variable should I cast to the other?
if((size_t)sst == st){...}
or
if(sst == (ssize_t)st){...}
What is safer, better, cleaner? Thanks
There is no one right answer to this question. There are several possible answers, depending on what you know a priori about the values that those variables may take on.
If you know that sst is non-negative, then you can safely cast sst to size_t, as this will not change the value (incidentally, this is what happens if you have no cast at all).
If sst might be negative but you know that st will never be larger than SSIZE_MAX, then you can safely cast st to ssize_t, as this will not change the value.
If sst might be negative, and st might be larger than SSIZE_MAX, then neither cast is correct; either one could change the value, resulting in an incorrect comparison. Instead, you would do the following if (sst >= 0 && (size_t)sst == st).
If you’re not absolutely certain that one of the first two situations applies, choose the third option as it is correct in all cases.
Either will work fine as long as both values fit in the positive representable range of ssize_t.
If either value doesn't, you could end up in trouble - check those cases before testing for equality:
if ((sst >= 0) && (st <= SSIZE_MAX) && (sst == (ssize_t)st))
{
...
}
(I'm sure the C++ people will recommend you avoid the C-style cast entirely - I have no doubt someone will comment or answer and let you know the right way to do that in C++.)
[This question is related to but not the same as this one.]
If I try to use values of certain types as boolean expressions, I get a warning. Rather than suppress the warning, I sometimes use the ternary operator (?:) to convert to a bool. Using two not operators (!!) seems to do the same thing.
Here's what I mean:
typedef long T; // similar warning with void * or double
T t = 0;
bool b = t; // performance warning: forcing 'long' value to 'bool'
b = t ? true : false; // ok
b = !!t; // any different?
So, does the double-not technique really do the same thing? Is it any more or less safe than the ternary technique? Is this technique equally safe with non-integral types (e.g., with void * or double for T)?
I'm not asking if !!t is good style. I am asking if it is semantically different than t ? true : false.
The argument of the ! operator and the first argument of the ternary operator are both implicitly converted to bool, so !! and ?: are IMO silly redundant decorations of the cast. I vote for
b = (t != 0);
No implicit conversions.
Alternatively, you can do this: bool b = (t != 0)
Careful!
A boolean is about truth and falseness.
An integer is about whole numbers.
Those are very distinct concepts:
Truth and falseness is about deciding stuff.
Numbers are about counting stuff.
When bridging those concepts, it should be done explicitly. I like Dima's version best:
b = (t != 0);
That code clearly says: Compare two numbers and store the truth-value in a boolean.
All valid techniques, all will generate the same code.
Personally, I just disable the warning so I can use the cleanest syntax. Casting to a bool is not something I'm worried about doing accidentally.
Yes it is safe.
0 is interpreted as false, everthing else is true,
hence !5 comes out as a false
!0 comes out as true
so !!5 comes out as true
I would not use:
bool b = !!t;
That is the least readable way (and thus the hardest to maintain)
The others depend on the situation.
If you are converting to use in a bool expression only.
bool b = t ? true : false;
if (b)
{
doSomething();
}
Then I would let the language do it for you:
if (t)
{
doSomething();
}
If you are actually storing a boolean value. Then first I would wonder why you have a long in the first places that requires the cast. Assuming you need the long and the bool value I would consider all the following depending on the situation.
bool b = t ? true : false; // Short and too the point.
// But not everybody groks this especially beginners.
bool b = (t != 0); // Gives the exact meaning of what you want to do.
bool b = static_cast<bool>(t); // Implies that t has no semantic meaning
// except as a bool in this context.
Summary:
Use what provides the most meaning for the context you are in.
Try and make it obvious what you are doing
I recommend never suppressing that warning, and never using a c cast (bool) to suppress it. The conversions may not always be called as you assume.
There is a difference between an expression that evaluates to true and a boolean of that value.
Both !! and ternary take getting used to, but will do the job similarly, if you do not want to define internal types with overloaded casts to bool.
Dima's approach is fine too, since it assigns the value of an expression to a bool.
If you're worried about the warning, you can also force the cast: bool b = (bool)t;
I really hate !!t!!!!!!. It smacks of the worst thing about C and C++, the temptation to be too clever by half with your syntax.
bool b(t != 0); // Is the best way IMHO, it explicitly shows what is happening.
Comparison to 0 doesn't work so well.
Which comes back -- why !! vs. ternary?
class foo { public: explicit operator bool () ; };
foo f;
auto a = f != 0; // invalid operands to binary expression ('foo' and 'int')
auto b = f ? true : false; // ok
auto c = !!f; // ok
!! may be compact, but I think it is unnecessarily complicated. Better to disable the warning or use the ternary operator, in my opinion.
I would use b = (0 != t) -- at least any sane person can read it easily. If I would see double dang in the code, I would be pretty much surprised.
Disable the warning.
Write for clarity first; then profile; then optimize for speed, where required.
!! is only useful when you're using a boolean expression in arithmetic fashion, e.g.:
c = 3 + !!extra; //3 or 4
(Whose style is a different discussion.) When all you need is a boolean expression, the !! is redundant. Writing
bool b = !!extra;
makes as much sense as:
if (!!extra) { ... }
I recommend to use
if (x != 0)
or
if (x != NULL)
instead of if(x); it's more understandable and readable.
The double not feels funny to me and in debug code will be very different than in optimized code.
If you're in love with !! you could always Macro it.
#define LONGTOBOOL(x) (!!(x))
(as an aside, the ternary operator is what I favor in these cases)
I would use bool b = t and leave the compile warning in, commenting on this particular line's safety. Disabling the warning may bite you in the butt in another part of the code.