4

When programming with Visual C++, I think every developer is used to see the warning

warning C4800: 'BOOL' : forcing value to bool 'true' or 'false'

from time to time. The reason obviously is that BOOL is defined as int and directly assigning any of the built-in numerical types to bool is considered a bad idea.

So my question is now, given any built-in numerical type (int, short, ...) that is to be interpreted as a boolean value, what is the/your preferred way of actually storing that value into a variable of type bool?

Note: While mixing BOOL and bool is probably a bad idea, I think the problem will inevitably pop up whether on Windows or somewhere else, so I think this question is neither Visual-C++ nor Windows specific.

Given int nBoolean; I prefer this style:

  • bool b = nBoolean?true:false;

The following might be alternatives:

  • bool b = !!nBoolean;

  • bool b = (nBoolean != 0);

Is there a generally preferred way? Rationale?

I should add: Since I only work with Visual-C++ I cannot really say if this is a VC++ specific question or if the same problem pops up with other compilers. So it would be interesting to specifically hear from g++ or users how they handle the int->bool case.

Regarding Standard C++: As David Thornley notes in a comment, the C++ Standard does not require this behavior. In fact it seems to explicitly allow this, so one might consider this a VC++ weirdness. To quote the N3029 draft (which is what I have around atm.):

4.12 Boolean conversions [conv.bool]

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. (...)

Martin Ba
  • 37,187
  • 33
  • 183
  • 337

7 Answers7

8

In the context of using win32 SDK and MFC, I tend to write it always this way. It's explicit.

bool b = (myBOOL != FALSE);

EDIT: I have edited :-) cause i'm not sure myBOOL == TRUE works for all implementation of BOOL and I can assume that FALSE may have the 0 value most of the time.

Stephane Rolland
  • 38,876
  • 35
  • 121
  • 169
  • 4
    If FALSE doesn't have value 0, you're already in deep trouble. – David Thornley Jan 31 '11 at 15:04
  • @David, look at `#define VARIANT_TRUE ((VARIANT_BOOL)-1)` in windows defined types... ;-) so `(VARIANT_TRUE == TRUE) == FALSE` :-) – Stephane Rolland Jan 31 '11 at 15:11
  • 3
    -1 `FALSE` is not a standard C++ value, and comparing boolean values with false and true just says the programmer is utter novice – Cheers and hth. - Alf Jan 31 '11 at 15:15
  • 1
    @Alf: That's not fair, because neither is BOOL which is in the error message that the OP quotes. It's not unfair for him to be using TRUE and FALSE here. – Puppy Jan 31 '11 at 15:17
  • @Stephane: that's really impressive. i only reacted to the technical. hope that's ok. – Cheers and hth. - Alf Jan 31 '11 at 15:37
  • @Alf: I'm with DeadMG here. The warning is `'BOOL' : forcing value to bool 'true' or 'false'`. That `BOOL` knows two values, named `TRUE` and `FALSE`. For that `BOOL`, `FALSE` is the right answer. @Stephane: It might help to split your answer in two, one dealing with `BOOL`, the other with all the other possible types. Nevertheless, `+1` from me. – sbi Jan 31 '11 at 19:43
  • @sbi: no, `BOOL` was originally very much multi-valued (e.g. as result type of `DialogProc`), not just `TRUE` and `FALSE`. Hence for comparision, if forced to that, I'd prefer comparing against 0. Comparing against a boolean value makes people reading the code pick up bad habits, and then some of them are going to compare against `TRUE`, and bang. So, it's ungood. Cheers, – Cheers and hth. - Alf Jan 31 '11 at 19:55
  • @Alf, I agree that TRUE may have different values, but as @David said: if FALSE is not 0... then that BOOL will hardly perform boolean logic: we must have FALSE && TRUE == FALSE while TRUE && TRUE == TRUE and FALSE && FALSE == FALSE. I may be wrong, be I dont see another value than 0 for FALSE that can perform that. – Stephane Rolland Feb 01 '11 at 02:33
  • @Alf I never thought/felt that comparing against literally 'true' or 'false' in the code may be bad habbit. I'm gonna think of it. – Stephane Rolland Feb 01 '11 at 02:39
  • @Stephane: there is a possibility that you misunderstood what I wrote. Windows `BOOL` is just a [`typedef` for `int`](http://msdn.microsoft.com/en-us/library/aa383751%28v=vs.85%29.aspx). Historically and possibly still it allows any non-zero value as logical True, and requires 0 as logical False. So, *technically* your code is OK. The problem comes when someone copies that idiom and does a similar comparison with `TRUE`, when the `BOOL` is say 345; that will then be a bug. A general convention should IMO not make such bug possible. It should Just Work™ without having to understand it. Cheers, – Cheers and hth. - Alf Feb 01 '11 at 10:07
  • @Alf, yep, in this case I understand. It's the reason I edited immediatly, because my first post was indeed comparing against TRUE ;-). hmm hmm. But I edited just some seconds after having posted while suddenly remembering all of my bugs with VARIANT_TRUE, which value is defined -1. – Stephane Rolland Feb 01 '11 at 11:14
4

The correct way I'd assume is:

bool b = static_cast<bool>(val);
Viktor Sehr
  • 12,825
  • 5
  • 58
  • 90
  • This doesn't do away with the warning in question, which is what the OP wants to do. – rubenvb Jan 31 '11 at 14:57
  • Correct from a std C++ POV? This will still generate a warning in VC++. Do you use this with another compiler? – Martin Ba Jan 31 '11 at 14:59
  • 6
    @Martin: The C++ standard has no problems with assigning an `int` to a `bool` without a cast (section 4.12), it being a standard conversion, so the only question is what to do about the compiler warning. Personally, I think this is a defect in VC++, and that the cast should shut the compiler up, but that's not actually relevant here. – David Thornley Jan 31 '11 at 15:08
  • -1 doesn't work for the intended purpose. since I always provide an explanation with every downvote, as e.g. *Jeff recommends*, apparently a moderator with a streak for annoying people, or perhaps just a bit retarded (i've had the misfortune to bump into at least one and possibly two such here on SO), has removed my earlier comment. so, reposting. and, to any braindead mod with an urge to delete again, check out Jeff's recommendations. of course, i do not expect such advice to work, but just for completeness. – Cheers and hth. - Alf Sep 18 '12 at 17:30
2

I cast my vote for

BOOL nBoolean;
bool b = (nBoolean != 0);

Reason? Since BOOL resolves to an int, one should compare it to an int when converting to bool. The other two methods: !!nBoolean and nBoolean?true:false treat nBoolean as as logical value and therefore perform an implicit cast conversion.

ThomasMcLeod
  • 7,603
  • 4
  • 42
  • 80
2

Three good ways:

static_cast<bool>( whatever )
bool( whatever )
!!whatever

Personally I prefer the last, but *nix folks may react negatively (not needed for those compilers, so not familiar with that idiom).

One reason that the last one is good is that it shuts up Visual C++ (sillywarning suppression).

Ungood ways include comparing with true or false, especially the former.

Cheers & hth.,

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • 1
    !! is used even on *nix, though usually for code-obfuscation-like constructs: `"01"[!!(some_expr_not_of_bool_type)]`. Personally I find the !! to be too obtuse and bool() always results in a static cast (rather than other "C++-style casts" a function-style cast can employ), so the first two are equivalent with my personal preference on the second. – Fred Nurk Jan 31 '11 at 15:37
  • Since the first two do not suppress the warning, what purpose do they serve? (They are not needed with other compilers or with the C++ Std, so I fail to see why one should write them?) – Martin Ba Jan 31 '11 at 16:32
  • @Martin: as I wrote, the last one shuts up Visual C++. The two first are very clear and standard C++ ways to convert to bool where needed. Some very good programmers (that includes the one who writes the standard) have stated publicly that warnings are best ignored instead of suppressed, and such a programmer might prefer the clarity, since there will be warnings anyway. – Cheers and hth. - Alf Jan 31 '11 at 16:46
  • 1
    "warnings are best ignored instead of suppressed" - this is simply wrong, as it would be difficult to notice that there is a new warning in the bunch of old ones, while this new warning can be about something important. – Roman L Jan 31 '11 at 18:41
  • @7view: I don't think it's a tenable position to say that those who wrote the tools that you use (like in this case, portions of Visual C++'s standard library), and penned the language standard that you rely on (in this case, C++0x draft), are "simply wrong" about their preferred tool usage. it may be that what suits someone else, someone of very high expertise, doesn't suit you. but i have the same *preference* as you, 100% clean compiles. – Cheers and hth. - Alf Jan 31 '11 at 19:40
1

I tend to write it always this way. .

bool b = !!myBOOL;

It is clearer (well as an English speaker, I am used to double-negatives....)

It is also safer and avoids mistakes like:

bool b = (myBOOL = FALSE); //oops!

Also, I am of the opinion that booleans should never be compared using == or != rather && should be used. As soon as == or != is used the boolean variable is no longer treated as a boolean but as an integral value which defeats the purpose of boolean.

T33C
  • 4,341
  • 2
  • 20
  • 42
  • @Maxim Yegorushkin - don't understand your point about clutter and don't understand how I can be downvoted for answering the question which was "What is my preference?" :/ – T33C Feb 01 '11 at 08:46
  • +1 to counter anonymous unexplained apparently mindless downvote. – Cheers and hth. - Alf Sep 18 '12 at 17:33
1

There is no preferred way in C++, since the C++ Std simply allows the integral conversion from int to bool. (So the preferred way wrt the Std would be bool b = i;.)

That said, judging from the other answers, there does not even seem to be an accepted way to do it in Visual C++ (MS) although the MSDN page states

... If you cannot rewrite the expression to use type bool, then you can add "!=0" to the expression, which gives the expression type bool. ...

So one might conclude that MS recommends to use the !=0 comparison, although I, personally, think it's the worst of all the warning-supressing alterantives presented in the question and the answers here: The "type" in the source code is BOOL, and even though it's really just an int at least one should compare a "BOOL" with !=FALSE like has been proposed in some other answers.

Martin Ba
  • 37,187
  • 33
  • 183
  • 337
  • 1
    @Cheersandhth.-Alf - I know that `!!` works (to shut up the warning). In fact all three of the examples I already gave in the question do work. The question was whether there be a preferred way, and as far as I'm concerned, the only acceptable answer is the one I gave here, namely that since GCC etc. do not even *have* such a warning/problem, there is simply no general preferred way for this, IMHO. – Martin Ba Sep 19 '12 at 04:21
-1

If this bothered me, I would write a helper function like

inline bool to_bool(BOOL b) {...}

which would hide one of the proposed implementations inside it. And never think about this again :)

Roman L
  • 3,006
  • 25
  • 37