1

I like (bool) way more, but it generates warnings. How do i get rid off the warnings?

I have code like:

bool something_else = 0;

void switcher(int val = -1){
    if(val != -1){
        something_else = (bool)val;
    }else{
        something_else ^= 1;
    }
}

Should i just do it like everyone else and use '!!' or make it somehow hide the warning messages when using (bool) ? Or is '!!' actually faster than (bool) ?

I would like to use (bool) and so i have to hide the warning, but how?

Edit: Visual Studio 2008 i am using, sorry i forgot to tell.

Edit 2: The warning message is warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning) And it comes on the line something_else = (bool)val; And on the line something_else = val; But not on the line something_else = !!val;

The problem is, i want it to respect that i want to convert it to boolean. I dont want to hide all boolean warnings, because sometimes they saved my ass.

Newbie
  • 1,593
  • 10
  • 35
  • 50
  • I get no warning when explicitly casting with `(bool)`; could you post more details? The warning you're talking about and the compiler you're using would help. – user229044 Mar 13 '10 at 18:35
  • Where do you get the warning? I'd say that it is `^= 1` that should produce the warning, while you seem to be talking about the `(bool)`. This just doesn't make sense. Again, re-check what is causing the warning in your case. – AnT stands with Russia Mar 13 '10 at 18:37
  • A coworker of me actually did `*reinterpret_cast(&some_int)` to work-around that warning. It soo made my eyes bleed – Johannes Schaub - litb Mar 13 '10 at 18:40
  • 4
    @Johannes: Ugh... As we all know the proper way to do it is `reinterpret_cast(some_int)` :) – AnT stands with Russia Mar 13 '10 at 18:50
  • Explicitly casting int to bool should not be causing a warning. You might want to recheck that the warning is marking the line that you think it is. – Alan Mar 13 '10 at 20:40
  • @Alan: It is a VC++ warning recognizably paraphrased in the title. IMO VC++ has a nasty habit of warning about things that you couldn't care less about (including "#pragma warning: there's no warning '4609'" which I keep getting from `` :) - I see no other option than not to enable full warnings (/W2 seems OK) ) – UncleBens Mar 13 '10 at 21:24
  • @UncleBens: You can use `#pragma` to shut off specific errors. The compiler is warning here because the compiler is telling you there's a hidden branch dependency in that code. Essentially the compiler has to expand it to an if/else branch because `bool` can only hold 0 or 1, and the compiler needs to handle the case that the int might be 42. – Billy ONeal Mar 14 '10 at 00:29
  • 2
    reinterpret_cast is the worst possible way to do it. The best is !!, and the second best is != 0 (or vice versa, depending on your taste) – Pavel Radzivilovsky Mar 14 '10 at 00:37
  • 2
    @Pavel: I think the reinterpret_cast comment was a joke. The best way is !=0 though and that is the form in fact requested by Visual Studio's documentation. – Billy ONeal Mar 14 '10 at 00:40
  • check my edits, i actually dont want to hide the error message completely, just alter its function. It made sense to me that the error message could have disappeared after (bool), just like float error messages disappears after (int)somefloat. But apparently i was wrong. – Newbie Mar 14 '10 at 13:06
  • @Pavel, it's undefined behavior to do it with `reinterpret_cast`. This can easily end up in the `default:` part: `int a = 3; switch(reinterpret_cast(a)) { case true: case false: break; default: ... ; }`. The coworker not only did it allwrong, but also did an unnecessary `&` and `*` operation, which i think @AndreyT was referring to. – Johannes Schaub - litb Mar 14 '10 at 18:55
  • @AndreyT ^^ notification-comment-workaround-placed-here. – Johannes Schaub - litb Mar 14 '10 at 18:56

6 Answers6

14

You should use operators and constructs specific to the bool type:

bool something_else = false;

void switcher(int val = -1)
{
    if(val == -1)    // val is -1 by default so THIS part is likely to execute
        something_else = !something_else;
    else
        something_else = (val != 0);
}

If your nickname is self-explanatory, it may make sense to write code that others will also understand. In case of this particular question, using the bool type appropriately will surely improve your further co-operation with other developers.

Kerido
  • 2,930
  • 2
  • 21
  • 34
  • I dont want to make the code look weird like that. check my edits if theres anything you know about? – Newbie Mar 14 '10 at 13:07
  • 2
    @Newbie: So you seriously mean that the code in your question isn't weird? Well, good luck! Otherwise, I just don't get whose code is weird. – Kerido Mar 14 '10 at 13:13
7

You can make the implied conversion explicit with (val != 0). The behaviour will be the same as a cast to bool, or !!, but makes your intent explicit with respect to the type of val.

Adam Wright
  • 48,938
  • 12
  • 131
  • 152
  • Why the downvotes? This is the code the compiler must generate to handle the cast correctly, and the branch dependency is what it's warning you about. – Billy ONeal Mar 14 '10 at 00:30
2

I get a warning with VC++:

main.cpp:5: warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)

You can work around it if you don't "force" the value into bool, but assign a value that already is boolean:

something_else = val != 0;

(Don't ask me why this deserves to be a warning - among warnings that inform you of serious problems (/W3). IMO, it would be a lot better to have a special flag to turn on warnings of such questionable value.)

But what is the bigger picture: toggle or use val (where -1 represents "don't use")?

How about:

bool something_else = 0;

void switcher(bool val, bool use_val = false){
    if(use_val){
        something_else = val;
    }else{
        something_else = !something_else;
    }
}

Or with tribool (never used it before): :)

#include <boost/logic/tribool.hpp>

bool something_else = false;

void switcher(boost::tribool val = boost::indeterminate){
    if(!indeterminate(val)){
        something_else = val;
    }else{
        something_else = !something_else;
    }
}
UncleBens
  • 40,819
  • 6
  • 57
  • 90
  • So there is no way to work around the specific warning? Only disable bool warnings completely? I dont want that since its sometimes useful warning. Also i dont want to make my code any more complicated because of that one warning... – Newbie Mar 14 '10 at 13:09
  • yeah and thats not gonna happen, i dont want to add complexity for such thing. – Newbie Mar 14 '10 at 16:24
  • I don't think this adds any "complexity", even though I'm no big fan of those warnings myself (e.g the tribool example produces 87 assorted warnings about added padding and removed inline functions with /Wall). – UncleBens Mar 14 '10 at 19:33
2

I would like to use (bool) and so i have to hide the warning, but how?

Why don't you consult the compiler's documentation on the warning? http://msdn.microsoft.com/en-us/library/b6801kcy(VS.71).aspx

This warning is generated when a value that is not bool is assigned or coerced into type bool. Typically, this message is caused by assigning int variables to bool variables where the int variable contains only values true and false, and could be redeclared as type bool. If you cannot rewrite the expression to use type bool, then you can add "!=0" to the expression, which gives the expression type bool. Casting the expression to type bool will not disable the warning, which is by design.

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • Yeah != makes no sense to me in that kinda of code, not gonna use it. I just wish there was way to fix that specific warning when i convert int to bool by telling "convert int to bool", i understand that if you dont tell it to covert it to bool its good to show warning – Newbie Mar 14 '10 at 13:10
  • You think != 0 makes less sense than !!? That seems odd to me, but whatever. The reason for the warning is that in order to convert to bool, the compiler must insert a branch instruction into the compiled code. Branch instructions are performance sensitive, and the compiler wants you to know that you aren't getting that conversion for "free" like you do when you cast between most other types. By writing != the branch dependence is clear from a simple examination of the program. – Billy ONeal Mar 14 '10 at 19:21
0

I don't suggest it in this case, but you can always #pragra warning disable.

#pragra warning disable # [, #]

It also may be based on compiler warning level (http://msdn.microsoft.com/en-us/library/b6801kcy(VS.80).aspx).

kenny
  • 21,522
  • 8
  • 49
  • 87
-4

another way:

switch (val) {
  case -1: something_else = !something_else; break;
  case  0: something_else = false; break;
  default: something_else = true; break;
}
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • You must have no idea what overcomplicated code looks like. And because you came here and asked a question with absolutely no interest in the answer, I'm starting to think you're a troll. – Ben Voigt Mar 14 '10 at 17:56
  • 3
    thats not the answer im looking for, i look a way to hide the warning of that specific case. im not gonna make my functions a mess like that, sorry. im asking "How do i get rid off the warnings?" not "how to program?" – Newbie Mar 14 '10 at 22:21
  • Then change your question to say you want to keep using the same code but hide the warning. You've got answers that tell you that too. But most people who say they want to "get rid of the warning" mean they want to FIX the code so it doesn't produce a warning, not just tell the compiler to shut up. And your "should I do it with !!" suggests that you were looking for the most correct way, not just inhibiting the warning. Well, "!= 0" is the best way to rewrite the single line, and my switch statement is the clearest way to rewrite the entire function. – Ben Voigt Mar 15 '10 at 00:55
  • fair enough, now when i think about it, i think this is the best way – Newbie Mar 15 '10 at 12:06