Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I think the compiler is just wrong. In C, zero is false and non-zero is true. Testing just the bottom bit was wrong.

Wikipedia, Boolean in C:

  if, while, for, etc., treat any non-zero value as true


You're misreading what's going on. The if test is indeed testing for a non-zero value. The "problem" is the negation only flipped the LSB in the register, thus leaving behind a non-zero value that passed the second if test. This is perfectly legitimate, since the value is undefined, and if it wasn't the compiler would have already ensured it only contained 0 or 1.


I read all that. If false is zero and true is anything else, its incorrect behavior to assume anything about the value - a test for zero or non-zero is the only legitimate test. I may have passed in 55 as a value for 'true' since any non-zero value is supposed to be true (not false anyway).


You still don't understand.

The if test is correct. It's using non-zero as "truth". That's what you're talking about, and there's absolutely no question that it's doing the right thing here.

The negation is not using non-zero for truth, because it's a negation of a bool, and bools are restricted to only being 0 and 1. However since this particular bool is undefined, the in-memory representation happens to not meet that restriction. But that doesn't matter. The value is undefined. The negation could, quite legally, cause demons to fly out your nose. The fact that you've observed, prior to the negation, that the value appears to be true has no meaning. Undefined values remain undefined even after observation and after manipulation.


Ah. So its the bool type itself that's broken. If an int type was used to store logical operations, the contradictory result is impossible (both true and not true).


Nothing is broken. The compiler would be within its rights to do the same thing to an int (or more realisticly a char or similar type that's shorter than the registers its stored in).


Yes, sure, but why design a language that way? Who is it helping? No language implementer WOULD do that to an int. My development group avoids bool like the plague, using int instead - it has well-defined size, behavior and sensible warnings.


>Yes, sure, but why design a language that way? Who is it helping?

Compiler writers. C exists mostly to be a portable language that's easy to compile. A better question is why would you write programs in C in 2012.

>No language implementer WOULD do that to an int. It certainly happened to float/double on some older architectures where the internal representation included different flag bits. I wouldn't be at all surprised if it happened to char and short. I guess there's an argument for using int for all variables in your program (since memory isn't usually constrained enough nowadays for it to be worth using short etc.), but again, if you weren't memory-constrained why would you be using C?

>My development group avoids bool like the plague, using int instead - it has well-defined size, behavior and sensible warnings

Int might not suffer from this particular behaviour, but if you use an uninitialized variable it will bite you sooner or later. The article's takeaway isn't "avoid bool", it's "initialize your variables"


Maybe you misapprehend the bool issue? It isn't that bool doesn't match a register; its that the value is stored in memory in a subset of the storage unit i.e. 1 bit out of the byte. That's not true of any other scalar.


Suppose you have a char followed by a long in a struct; the compiler will insert seven bytes of padding after the char. There's nothing to prevent it setting the padding to 0 when initializing the char, and using a 64-bit load instruction to load it into a register - in which case you'd get exactly the same behaviour as seen here with bool, only even more confusing.


This is true for integers and pointers. The bool type (introduced in C99) though, is only required by C as to have the value 0 or 1. If you assign 55 to a bool, there are rules that implicitly convert that to a 1. If an implementation chooses to make bool only store 0 and 1, and you somehow manages to squeeze another value into that bool, it's perfectly fine for this to be undefined behavior.


6.3.1.2 Boolean type

"When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1"

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf page 43


The built-in boolean type only has two values, 0 and 1. Anything else in the memory means it's not actually a value of that type.




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

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

Search: