
Linus: bool is dangerous in C if you don't understand it - general_failure
https://lkml.org/lkml/2013/8/31/138
======
ridiculous_fish
Here's the advantage of C99's bool. Lots of C projects do something like this:

    
    
        typedef char bool;
    

and then maybe they use it like so:

    
    
        bool found_it = strstr(haystack, needle);
    

This has a serious bug that will only manifest 0.4% of the time. The problem
is that strstr returns a pointer, and converting a pointer to a smaller
integer type throws away the high bytes. If the resulting pointer is not NULL
but happens to have a zero low byte, this bool will be false, even though the
string was found.

Even if that doesn't happen, you'll often see code like this:

    
    
        #define true 1
        ...
        if (found_it == true) ...
    

which is wrong as well.

bool addresses these. Conversions to bool always result in values of 0 or 1,
so both of the above problems are avoided.

That said, I agree with Linus. It's not well understood, and using bool in a
library header may conflict with another definition of bool in the project.
Also, compilers typically warn about at least the first error above. As a C99
feature, bool is too little, too late; had it been part of C89, things might
be different.

~~~
ajross
"warning: initialization makes integer from pointer without a cast"

I mean sure, there are warnings and there are warnings. Absurdist pedantry
about warning states isn't something I tend to worry about.

But if you're dealing with a code base that is building to completion without
attention to _this_ warning (which pops out with the default flags on gcc
4.7.2 -- no -Wall needed!), then you have more serious problems than can be
fixed by a builtin pointer-to-bool conversion.

~~~
ben0x539
Arguably that warning just suggests that you put in a cast, which makes it no
more correct. Then you get another warning "cast from pointer to integer of
different size [-Wpointer-to-int-cast]" which apparently is also on by
default, but I'm not sure it's immediately obvious to a casual C programmer
how that will go wrong.

~~~
ajross
Again, I'd argue that if you have a programmer willing to throw in a double
cast expression (!) to work around a warning without once thinking about what
they are trying to do (in this case to check if a pointer is NULL) then you
have problems that aren't going to be well addressed by a C99 bool anyway.

I mean, this example is a little contrived as it is. The "normal" way to treat
a pointer as a boolean and branch off of it is just "if(ptr)", and that's
worked without trouble on all compilers for 40 years now.

Is C sort of a mess? Yeah. But this isn't a particularly illustrative example
IMHO. All languages have this nonsense (c.f. the Ruby/JS "Wat" video).

------
kingkilr
Really though, what _isn 't_ dangerous in C if you don't understand it. (Hell,
most of C is dangerous even if you understand it).

~~~
timothya
I think the point he is trying to make is that most people _think_ they
understand it when they really don't.

------
chatman
The biggest upside is better readability of code, esp. when you're glancing
over documentation of functions.

------
michaelcampbell
> Linus: bool is dangerous in C if you don't understand it

What in C is NOT dangerous if you don't understand it?

~~~
EpicEng
What in <any language> is not dangerous if you don't understand it?

~~~
gdy
Strong typing?

~~~
EpicEng
...fair enough.

------
pivnicek
Never understood why we needed a boolean type, myself. What is wrong with 1
and 0?

~~~
fredsanford
What's wrong with anything that's not false is true?

If you treat it this way you remove the vast majority of the problems with
most C or C++ BOOL implementations.

The low bytes of a pointer being 0 (It can happen on Windows with VirtualAlloc
and company) can screw up the works, so avoid assigning a pointer to a BOOL
and use BOOL b = !!pointer if you have to break that rule.

~~~
chrismcb
Why not make the correct comparison and do BOOL b = pointer != NULL. Now the
code says what you mean, is easy to understand, and assigns a boolean value to
a bool.

~~~
to3m
!!p does the same as p!=NULL. The choice is purely stylistic. (!p is
equivalent to p==NULL; !!p is therefore equivalent to !(p==NULL). Or,
alternatively, p!=NULL.)

------
slackpad
C++ tried to use template specialization with std::vector<bool> to take
advantage of bool-ness and provide a dense storage for bits, but it suffers
for reasons Linus points out here, namely the inability to cleanly address
individual elements of the vector (so it doesn't behave exactly like a normal
std::vector).

~~~
twoodfin
Right. At the time, as I understand it, the standards committee thought
reference semantics and operator overloading would be powerful enough to
create perfect "proxy" objects that would be indistinguishable from their
direct equivalents. std::vector<bool> ended up demonstrating the opposite.

std::bitset<N> is quite nice though, as long as you have a fixed size.

------
eliasmacpherson
Don't think anyone has mentioned this:

bool is also subject to integer promotion so when you pass a bool to a
function or do some integer arithmetic it can become an int.

From the text K&R, C Programming Language, 2nd Ed. p. 174

A.6.1 Integral Promotion

A character, a short integer, or an integer bit-field, all either signed or
not, or an object of enumeration type, may be used in an expression wherever
an integer may be used. If an int can represent all the values of the original
type, then the value is converted to int; otherwise the value is converted to
unsigned int. This process is called integral promotion.

------
altrego99
Using bool in C, as well as C++ has distinct advantages. If Linus or some
idiot cannot control himself from making mistakes, and from causing serious
damage to the code, it is his fault. You can always aim it at your foot given
any construction tool. I don't care if fools can't control it, but I wouldn't
say no to bool.

~~~
primelens
Wow, I'm sure there's plenty of things to vehemently disagree with Torvalds on
and even to criticize him - manners, politics, management style and even the
finer points of programming. But I would have thought he'd earned his stripes
enough to at least not to be called an idiot on his C skills on HN. But
apparently not. Next up, Dennis Ritchie!

~~~
solistice
Just as inexperienced as this Kerningham guy.

On the other hand, I'm happy if my C code compiles, so I shouldn't throw any
stones here.

------
StephenFalken
"variadic macros and bool are just adornment" in _The future according to
Dennis Ritchie (a 2000 interview)_ [1]

[1]
[http://www.itworld.com/lw-12-ritchie?page=0,1](http://www.itworld.com/lw-12-ritchie?page=0,1)

------
kineticfocus
I recall a recent post that looks at other definitions of the boolean ...
[http://nshipster.com/bool/](http://nshipster.com/bool/)

We need to develop one universal standard... :)

------
tonetheman
I read the article and in fact the versions of stdbool look pretty close to
what he said.

Maybe there is some subtly there I am missing but I do not see it.

~~~
induscreep
The subtlety is that bool expands to _Bool, not int. So bool is actually a
macro, not "typedef int bool" as in Linus' example code snippet.

~~~
yuubi
The important bit seems to be the behavior of the _Bool type, not the
macroness (also, the [Future Directions section of the Open Group
spec]([http://pubs.opengroup.org/onlinepubs/007904875/basedefs/stdb...](http://pubs.opengroup.org/onlinepubs/007904875/basedefs/stdbool.h.html#tag_13_46_06))
says #undefing and redefining the macros is obsolescent, leaving open the
possibility of changing the implementation from a macro to something else
entirely).

------
adamgravitis
I think it's fair to say just about anything is dangerous in C if you don't
understand it...

------
clay
This documentation for stdbool.h says exactly what he says is wrong:

[http://pubs.opengroup.org/onlinepubs/007904875/basedefs/stdb...](http://pubs.opengroup.org/onlinepubs/007904875/basedefs/stdbool.h.html)

It's interesting though... does anyone know of specific cases of the problems
he's refering to?

~~~
revelation

        bool a = value & (1 << 5)
    

a will be 1 or 0, not 1 << 5\. You don't get this behavior with a normal int.
MSVC also has a warning about some of this behavior [1], with a nonsense
performance subtext. I don't think theres a GCC equivalent.

1: [http://msdn.microsoft.com/en-
us/library/b6801kcy.aspx](http://msdn.microsoft.com/en-
us/library/b6801kcy.aspx)

~~~
skybrian
Seems like the only reason you'd expect it to be 1 << 5 is that you've been
working with a broken definition of bool using #define.

In any sane language you can't redefine bool that way, nobody would ever
expect bool to take more than two values, and there wouldn't be a problem.

------
snarfy
Nobody ever said bool was a bit.

------
pmelendez
Well... Everything is dangerous in any language if you don't understand it.

~~~
derekp7
That may be true. However something is more dangerous if it is very easy (or
common) to mis-understand it. I think that is the point that Linus was trying
to get at -- bool is dangerous because it is likely to be misunderstood.

------
ksk
X is dangerous in Y if you don't understand it. Indeed.

~~~
TelmoMenezes
Sandwiches are dangerous in astronomy if you don't understand it?

~~~
jk4930
Of course. Imagine, during the assembly process, someone eats his sandwich
while hanging over the mirror of some space telescope. Do you think the all
those dots you're seeing on the NASA images are stars? And once they discover
the peanut butter nebula, they have to update parts of the astronomy books.

------
dscrd
I wonder if Linus has ever tried better languages.

~~~
dima55
Are you proposing the kernel be rewritten in a "better" language?

~~~
enneff
I have no idea how you derived that from that comment.

~~~
coldtea
He derived by you saying "better".

For what he does there is NO better language than C.

So what would be a "better language"? Haskell? In what way would it be better
-- since it wouldn't be better for the tasks he wants?

Abstract better?

Sorry, I don't believe in that.

~~~
dmit
Is C the best possible choice for Git? For Subsurface? For the embroidery
template converter thingie he wrote for his wife?

Linus used C for all of those, but was it because C was technically the best
choice in each case, or because it was good enough to get the job done and
because it's the language he's most comfortable with?

~~~
jlgreco
> _" Is C the best possible choice for Git?"_

Well, I mean...

    
    
      SLOC  Directory       SLOC-by-Language (Sorted)                              
      100691  top_dir         ansic=80140,perl=10458,sh=7523,python=2570           
      98482   t               sh=97926,perl=546,ansic=10                           
      38293   builtin         ansic=38293                                          
      22256   contrib         sh=9888,perl=5838,python=3130,lisp=1786,ansic=1449,  
                              php=120,csh=45                                       
      18056   compat          ansic=18004,perl=52                                  
      13754   git-gui         tcl=10299,sh=3455                                    
      10859   gitk-git        tcl=10745,sh=114                                     
      6225    gitweb          perl=6225                                            
      5400    perl            perl=5400                                            
      2350    xdiff           ansic=2350                                           
      1288    vcs-svn         ansic=1288                                           
      689     git_remote_helpers python=689                                        
      292     Documentation   perl=155,sh=137                                      
      266     templates       sh=266                                               
      203     block-sha1      ansic=203                                            
      173     ppc             asm=98,ansic=75                                      
      0       mergetools      (none)                                               
      0       po              (none)                                               
                                                                                   
                                                                                   
      Totals grouped by language (dominant language first):                        
      ansic:       141812 (44.42%)                                                 
      sh:          119309 (37.37%)                                                 
      perl:         28674 (8.98%)                                                  
      tcl:          21044 (6.59%)                                                  
      python:        6389 (2.00%)                                                  
      lisp:          1786 (0.56%)                                                  
      php:            120 (0.04%)                                                  
      asm:             98 (0.03%)                                                  
      csh:             45 (0.01%)
    

Git's design is such that different parts of it can be written in different
languages with no hassle. The majority _is_ in C, but typically new features
are prototyped out in other languages first until it becomes clear that speed
will be important (and it generally will, since a major usage pattern of git
is scripts and other commands calling your command many times in a row. Does
git-add need to be fast if you're just doing 'git add ...'? Perhaps not. Does
it need to be fast if my fancy-smancy script is wailing on it several thousand
times? Yeah; particularly it needs to have a fast startup time. Does git-
difftool need to be in C? Probably not, which is probably why it is still Perl
instead. Test-cases? No reason in the world for them to be in C, so they're in
sh.)

------
cLeEOGPw
Even after reading all the comments I am not sure should I use bool in C code
or not. I am C++ programmer only starting to have some fun in C.

Linus says: If "bool" had real advantages (like having a dense array
representation, for example).

But doesn't bool have the advantage of reducing perceived complexity of the
code and making the code more understandable? If the function returns int, one
might assume it is some number, and he would have to use documentation or look
at code samples to find out the int is only being compared to 1 or 0. Type
bool instantly tells there's some kind of check or flag that is returned, and
makes it undoubtedly easier to tell what's going on.

As for casting rules other mentioned, doesn't the C compiler warn about
anything converting to anything that can store less information than what it
converts from?

~~~
pavlov
Normally you get a warning when the destination type is smaller, but with C99
bool you don't because that's how the standard is written: any non-zero value
of any other type is implicitly converted to "true".

That's why C99 bool typecasting problems are so subtle. If you were previously
using _typedef char BOOL_ and you switch to the "real" bool, you don't get
compiler warnings about suspicious casting anymore.

~~~
andrewcooke
but you don't have the bug either, right? because it doesn't take only the
first byte. so what's the problem? (genuine question - have never used _Bool
and am trying to get a handle on this thread).

~~~
pavlov
Indeed, the C99 bool fixes this particular bug, but it can introduce new bugs
because its semantics are different from other C types. C99 bool allows you to
assign a larger integer or a pointer to a bool with no warning. As illustrated
by the grandparent commentor, the general assumption is that the C compiler
will always warn you about these situations.

If bool had been always been part of the standard, people would be aware of
this issue. But it wasn't, and so the C world is full of BOOL typedefs that
can be chars, ints or whatever, and it's easy for programmers to implicitly
assume that the "real" bool behaves like the typedefs they're used to.

------
losethos
My bool is a char. I'm not going to add junk to my compiler for actual bool
support. I guess I could explain that. I have a ToBool(StrStr()) function.

------
innguest
C: the language that can't even get a boolean type right.

And that stuff was standardized by a committee? Wow.

~~~
gizmo686
Why should C get boolean write. As a language, it is very close to the
hardware, and the hardware doesn't actually have the concept of a bit. The
smallest unit that modern processors expose is a byte, so it makes sense that
the smallest datatype C has is also a byte.

~~~
innguest
No need to define boolean in terms of a bit just because that's all it takes.
There's no harm in being redundant and using a whole byte for it, so that -1
is true and 0 is false.

