In C++, << has higher precedence than &&, so in effect what is being done is
(cout << 1) && 2;
...which is not an error, since the result of operator<< is an std::ostream, which is convertible to bool. Therefore operator&&(bool, bool) is invoked but the result is, of course, discarded.
Disambiguating the expression with parentheses should output 1 in every case.
Heh; my "age" is starting to show. The first version of Python I learned was Python 2.4 and it was only a few years ago I finally moved to 2.6. Skipping 2.7 and moving to 3.3+ soon.
Personally, I prefer the brevity of the older syntax, but to each his own. However, I understand the "ternary" expression was added because the older syntax was error-prone:
I can't claim to have worked with Perl much prior to Perl 5.6/5.8 though, so it may have been an older idiom (though I doubt it as one of Perl's influences was Awk, which also has a C ternary operator, IIRC).
That said, using truthy/falsey values in Python doesn't seem super common. I surprised a couple of interviewers by doing that while implementing some tree manipulation functions.
Nah mate, it's just some compiler flag that I didn't turn on (don't know which. my gcc-fu is fail since it's been really a long time since I touched C)
Yeah I'm dying to see the original C code but it isn't on the page anywhere, AFAICT.
From the article, about the C version: "Mine hadn't worked, which I suspect is some sort of compiler issue."
Yeah I'm going to go out on a limb and proclaim that there's no way this was due to a compiler "issue" in gcc. Not that gcc is perfect, but there's no way it is barfing on one of these handful of line programs that does nothing but some logical operations and printfs.
Parts of the blog post was written late last night (about 3 am), and parts of it was written on my commute to work. I tried to rewrite what I wrote last night and tried to compile it on my work computer, and all I got were warnings.
It's not a compiler flag, I guarantee it. Your code was simply incorrect. The only thing a compiler flag might have done was turn on a warning that would have told you what you did wrong (depending on what, exactly, you did do wrong).
Well, there is a difference between "format specifier" and "format string". The first argument to printf is the format string, the `%d` and `%s` type things are the format specifiers. I was talking about this
printf("Hi", 45);
which will not segfault. If you meant
printf(45);
Then you are absolutely correct, that would segfault on common machines.
Once you understand short-circuit evaluation, it opens up certain coding tricks.
The line "[operation] or [error condition]" will attempt the operation on the left. If it succeeds, the program continues on the next line, ignoring the part about the error condition. If it fails, the error condition will execute instead. This might be something like "open file or die".
Likewise, "[operation] and [success condition]" will attempt the operation on the left, and if it succeeds, perform the operation on the right. This might be something like "read input and process it", which will perform the (possibly expensive) processing step only when input is received.
Code written in this style is sometimes, but not always, faster to execute. It's also sometimes, but not always, clearer.
That code is the same, but or has a lower priority than ||, so they are not the same is the code before the or is an expression.
Also, using or instead or || for these types of things is more readable since it makes your intent of conditional code execution (as opposed to boolean evaluation) clear.
Meh, it's not more unreadable unless you have issues understanding || in the first place... and "or" is still a boolean operation.
Considering 99.9% of it's use in PHP is some variant of "connect() or die()", I stand by my statement. Besides, those "connect() or die()" expressions are widely considered bad-practice in the first place.
For fun, sometimes I'll rewrite JS trying not to use any explicit conditionals (keywords if/else/), and use short-circuiting instead. It's a fun exercise but I know better than to commit the code, I think I'd be dead several times over by now...
You wrote at the end that you weren't sure why literal values were returned instead of TRUE and FALSE. The practical answer is that literal values are far more useful. The simple answer is that, since the literal value already represents TRUE (or FALSE), returning it makes just as much sense as returning a literal TRUE/FALSE, and is simpler to do.
Common Lisp treats any non-nil value as "true," so the behavior is not bad for the "and" macro (yes, it is a macro). Additionally, the standard says that "and" should evaluate to nil if any argument evaluates to nil, or to its last argument otherwise:
It's not a new operator, but rather the X= form, where `foo X= 4` is sugar for `foo = foo X 4`
Just be careful with this in JavaScript, as the greater number of things that are falsy can bite you if you do `a = a || 10;`, which is a very common JS bug.
Watch out for this with boolean values. If you are attempting to memoize a method that returns a boolean, it'll be re-evaluated if the last iteration returned false.
Feel free to change it to how you like it if you feel that another syntax would be more convenient. You can choose another operator or just create a variadic template function and use function syntax to avoid operator precedence issues.
You mean, like, in the compiler? If x is actually a macro that expands to zero, that will (or at least should, for a sufficiently smart compiler) happen. Otherwise, I can’t imagine a runtime check of this being appreciably faster than hardware multiply. Right?
I would guess he/she meant something along the lines of x * some_really_complicated_expression. If x is 0, you would not need to evaluate the other operand at all. It may even be a faster, but I doubt any compiler does this sort of optimization, since it is not safe in languages with non-pure functions. The complicated expression could change some global state or perform input/output.
E.g. in Haskell, it would be possible to do this safely, because it is guaranteed by the type system that there are no side effects. However, even with literal 0 in the code the other operand still gets evaluated.
Disambiguating the expression with parentheses should output 1 in every case.