By Petruza


2010-04-27 20:54:36 8 Comments

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

4 comments

@CB Bailey 2010-04-27 20:56:55

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.

@Joshua 2010-04-27 21:01:42

This is true only for primitives. Beware of value of true coming from imports from other libraries.

@CB Bailey 2010-04-27 21:03:33

@GMan: Thanks for the vote of confidence. If a compiler promotes true to any other integer value then it's not a conforming C++ compiler.

@jalf 2010-04-27 21:04:21

@Joshua: true is a keyword defined by the language. It can not be redefined by a library. #defines are not allowed to redefine keywords.

@Franci Penov 2010-04-27 21:06:51

@Joshua - it's part of the language, so no library should be defining values for true. if you know of one that does it, please let us know so we can avoid it. :-) just like we would avoid any library that defines while.

@Dale Hagglund 2010-04-27 21:07:44

@jalf: #define's are indeed allowed to define system keywords. The pre-processing phase of C compilation is purely textual, and knows nothing of keywords or C syntax in general. Nevertheless, it is, of course, almost always a bad idea to redefine language keywords.

@Ken Bloom 2010-04-27 21:08:17

@jalf. They're not? See gcc.gnu.org/onlinedocs/cpp/Macros.html, and at least one of the entries in the International Obfuscated C Code Contest, which once asked "When does a while not take a while?" (Answer: when it takes two parameters, because then that entry had #defined it to printf.)

@David Thornley 2010-04-27 21:14:50

@Ken Bloom: The rules may be different between C++ and C.

@Jonathan M Davis 2010-04-27 21:23:14

I think that that it's quite safe to say that no compiler or library implementing the standard will redefine any keywords with macros because that would make it so that when any user of them used them, they would be in violation of the standard. So, in effect, they're guaranteed by the standard. However, there's nothing to stop you or a third party library from being stupid and redefining them.

@David Thornley 2010-04-27 21:25:41

@Joshua: true is a C++ keyword, and may not be used for any other purpose. 17.4.3.1.1 in the Standard forbids #define true ..., so no conforming program can have true mean anything other than the primitive bool value.

@Jerry Coffin 2010-04-27 21:29:15

C99, §6.10.1/1 says: "The expression that controls conditional inclusion shall be an integer constant expression except that: it shall not contain a cast; identifiers (including those lexically identical to keywords) are interpreted as described below;" Though not stated as direct permission, this clearly contemplates the possibility of a macro that's "lexically identical" to a keyword.

@Jerry Coffin 2010-04-27 21:33:25

@David Thornley: that's almost but not quite true. A translation unit is only prohibited from re-defining key words if it includes a header. A translation unit that was entirely self-contained (didn't depend on any headers) could apparently re-define keywords; whether it should or not is a separate question...

@dreamlax 2010-04-27 21:34:37

@David Thornley: If I'm reading that right, apparently it's OK to redefine true as long as you don't include a header.

@Dennis Zickefoose 2010-04-27 21:50:23

If that is true, then headers can obviously not do #define TRUE 9. And if a self contained file defines a function that returns a bool, and that unit used the preprocessor to change true to 9, then the compiler will simply convert that 9 back to true in the return statement. So there is still no way for true and false to be anything other than what they are unless you personally change them.

@Joshua 2010-04-27 22:47:26

What I meant was do not assume that a function in a third party library declared in a header file to return bool returns a true that cast as integer returns 1.

@Joshua 2010-04-27 22:49:37

Oh, and #defines are allowed to redefine keywords. C++1x caused too many problems with its new keywords so that requirement had to be removed.

@Ken Bloom 2010-04-28 00:57:06

The standard allows the C++ preprocessor to have the ability to redefine keywords, but programs that do so are not necessarily standards compliant.

@Georg Fritzsche 2010-04-28 01:07:45

Ken opened a new question for the discussion here: stackoverflow.com/questions/2726204/…

@Petruza 2010-04-28 13:23:50

Well, in case someone wants to use my library and re-defines true as something else than 1, it's their problem, not mine. :D

@David Thornley 2010-04-28 13:38:28

@Jerry: Thanks. I apparently read that too fast. Is there anything actually forbidding redefinition of keywords in general? Why would the ban apply only to translation units without headers?

@Lightness Races with Monica 2011-12-14 15:20:48

@Joshua: Why not? true always converts to 1. It doesn't matter if someone had originally done (bool)5 to get that true: (int)(bool)5 is 1.

@Joshua 2011-12-14 19:39:32

Trust me, don't assume it when crossing library boundaries. I've seen too many cases where a type bool casted back to char had some other value than 0 or 1. This also causes trues to compare unequally. && and || work correctly.

@CB Bailey 2011-12-14 22:16:58

@Joshua: You should complain to your compiler vendor. No currently maintained compilers that I know of still get this wrong.

@Joshua 2011-12-14 23:04:29

The compiler's not the problem.

@Jerry Coffin 2010-04-27 21:00:29

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

@Franci Penov 2010-04-27 21:04:12

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.

@Michael Dorgan 2010-04-27 20:59:05

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.

@David Thornley 2010-04-28 13:48:24

This is an incorrect answer for C++, as true is a language keyword with defined behavior. If you refer to a commonly defined macro such as TRUE, it is correct.

@Michael Dorgan 2010-04-28 14:46:05

Could be my experience was with C compilers - I've spent plenty of time with them over the years. My point about directly using mathetical expressions in if statements stands though. We had code that seeing if a bit shift was non zero in an if, then someone else took that same non-zero value and assumed it was 1 and blew stuff up. A simple conversion to true/1 would have prevented that.

@thb 2014-11-15 12:17:27

I too have seen behavior of this kind. Admittedly, the last time I saw it was about 1999. I was using GCC. The language was C. Still, I have indeed seen such behavior.

Related Questions

Sponsored Content

25 Answered Questions

16 Answered Questions

[SOLVED] How can I profile C++ code running on Linux?

  • 2008-12-17 20:29:24
  • Gabriel Isenberg
  • 489478 View
  • 1722 Score
  • 16 Answer
  • Tags:   c++ unix profiling

37 Answered Questions

76 Answered Questions

[SOLVED] How do I iterate over the words of a string?

  • 2008-10-25 08:58:21
  • Ashwin Nanjappa
  • 2138050 View
  • 2887 Score
  • 76 Answer
  • Tags:   c++ string split

5 Answered Questions

22 Answered Questions

[SOLVED] What is the "-->" operator in C++?

1 Answered Questions

[SOLVED] The Definitive C++ Book Guide and List

  • 2008-12-23 05:23:56
  • grepsedawk
  • 2235212 View
  • 4247 Score
  • 1 Answer
  • Tags:   c++ c++-faq

27 Answered Questions

[SOLVED] Easiest way to convert int to string in C++

23 Answered Questions

[SOLVED] Compiling an application for use in highly radioactive environments

5 Answered Questions

[SOLVED] What is the copy-and-swap idiom?

Sponsored Content