Hacker Newsnew | past | comments | ask | show | jobs | submit | clay's commentslogin

The article mentions law enforcement. I reckon these warrants are all for sex crimes.


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

http://pubs.opengroup.org/onlinepubs/007904875/basedefs/stdb...

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


Consider a simple bit mask operation, assume 8 bit ints for the sake of brevity:

Prior to C99, assuming you use the mentioned typedef for bool:

    bool a = someInt & 0x02
'a' will be 0x02 if the bit is set.

In C99, bool is aliased to _Bool and if the flag is set, the above code will result in 'a' being 0x01 because of C99's requirements for type conversion.

To accurately get the same behavior prior to C99, you can add !!, e.g.:

    bool a = !!(someInt & 0x02)  //'a' is now 0x01 when the bit is set.


Most, if not all, of the problems people are describing in this discussion come down to trying to assign something that isn't a boolean value to a variable of boolean type, and expecting it to do something sensible. I don't see how this is ever going to have a happy ending.

If you had written

    bool a = (someInt & 0x02) == 0x02
or something similarly clear and unambiguous, nothing odd would happen, even in C.

(Edit: OK, that's not strictly true, because of the operator precedence order. It's never made sense to me that integer arithmetic operators have higher precedence than comparisons but bitwise logical operators have lower precedence, so if you remove the parentheses above then the resulting code doesn't do what you'd expect. I suppose this is because I'm looking at the problem as if comparison operators return a proper boolean value rather than an integer, and the ordering we've wound up with in C dates from a historical oddity about 40 years ago.)

The underlying problem with booleans in C99, as Linus and others have been saying, is that the language doesn't actually enforce basic type safety, so cases like your first example

    bool a = someInt & 0x02
that should result in a type error are allowed through, and with odd results: how does it make any sense for a boolean variable to have an integer value like 0x01 or 0x02?

Then programmers who relied on such odd results wind up writing horrific code like your second example

    bool a = !!(someInt & 0x02)
where fudge factors build on top of distortions to make the old hacks work.

And then we wonder why in 2013 we still have widely used, essential software that is riddled with security flaws and crash bugs. :-(


The reason that & and | have lower precedence than the comparison operators is indeed historical - it's because the earliest versions of the language didn't have the logical boolean operators && and ||, so the bitwise & and | operators stood in for them. The lower precedence meant that you could write:

  if (x == 1 & y == 2) {
..and have it do what you meant. This became a bit of a wart when the && and || operators were introduced (still well before ANSI standardisation), but it was considered that changing it would have broken too much existing code.


    bool a = someInt & 0x02;
is perfectly fine in C99. 0 converts to false, non-zero converts to 1 when assigning to a _Bool.

What's not fine is people creating their own compatibility booleans where they define true as 1, as that would indeed break(rather odd..) code such as

    bool a = someInt & 0x02;
    if (a == true) 
If the bool above is not the C99 _Bool, but just a typedef to another integer type, you end up with if(0x02 == 1) evaluating to false.


> Then programmers who relied on such odd results wind up writing horrific code like your second example

What's horrific about that? Would it be better if we had:

    #define to_bool(_X) !!(_X)
    ...
    bool a = to_bool(someInt & 0x02);


but this - and other examples here - seem unfair, in that they are blaming _Bool for working correctly (consistently, logically) in cases where people were previously doing dumb things.

if you rely on something called "bool" being 0x02 you're going to have a bad time. that's hardly C99's fault.

your last line of code is what i would write, effectively, if i needed to compare booleans. it seems to me that _Bool is an improvement because, pre-C99, if i forgot the !! dance somewhere, i likely had a bug. with _Bool things just work.

(disclaimer, as with other reply here - still trying to get a grasp on this, so may be saying something stupid myself).


I don't really disagree, but Linus's point, which I agree with, is that C99's implementation is 'better' but is still pretty bad, i.e. 'bool' is still a mask for 'int' and as a result array's of bools aren't what they should be: bit arrays, directly serializing a bool is still sending out an entire int of data, etc. The 'improvement' in C99 isn't worth the broken code that will result from the subtle differences.

It's also worth considering in context that a lot of the code which will run into problems with these small differences is low level OS/driver code that often deals with a lot of bit flags and bit manipulation in general. When your trying to fit a web server into 3800 _bytes_ of ram on an 8 bit microcontroller, 'doing dumb things' becomes 'being inventive'.


C99 6.3.1.2 requires that converting nonzero to _Bool yields a 1. An int doesn't work that way.


    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


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.


But, this is the case in every other language I can think of. IE, bools have one of two possible states; as a human 1<<5 is neither true nor false.


You missed the part where _Bool is not the same as int.


Note that he also denounces the implicit conversion rules.


Dropbox did this recently with an email titled "Never email big files again! Share with a Dropbox link"


Rally.org - San Francisco

Building tools to help non-profits, charities, and other organizations fundraise and spread their message better.

Looking for:

  - Full stack web developers (Rails, Capistrano, chef, etc)
  - Data Scientists (machine learning, visualization, and front-end web development)
Our jobs page has more info https://rally.org/jobs

Email me at clay.woolam@rally.org and I'll get you connected


Here's a collection of pagerank values based on the followers graph from two months ago, if anyone's interested

https://raw.github.com/clayw/Github-pageranks/master/github-...


An awesome way to learn new tricks is to hack with another vim user


Or vim golf if there are no users nearby.


That's awesome. I didn't know about that.


It might service some of your watched repos because of data quality issues. It uses a very basic nearest neighbor shared item set model. I'm definitely planning on improving the quality of the results in the near future.



There were a few interesting repos in there I hadn't heard of - nice work!


Saving a snapshot of the page you bookmark at the moment you bookmark it is totally awesome. Great work guys.


except the Jesus topic, because of all the godless heathens in SF and NYC


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: