5 ms·
> I'm sorry, but the shockingly common belief that C's ternary operator has anything at all to do with branchless code being emitted is completely unhinged from
by xscott 4y ago
> I'm sorry, but the shockingly common belief that C's ternary operator has anything at all to do with branchless code being emitted is completely unhinged from reality.
Not sure what you're sorry about. The author doesn't seem to have made that mistake. It's not even a few paragraphs in before he says:
"One way that seems natural to get the compiler to generate branchless code is to use the ternary operator, but that does not work."
and later:
"Both GCC and Clang generate IR with branches for ternary operators (even with no side effects),"
Did you read any of the article? It doesn't really go into a lot of depth, but what's "shockingly common" is people who comment without reading.
- yxhuvud 4y agoWhat is not obvious is why anyone would think using ternaries would be a "natural" way of writing branchless code.
- xscott 4y agoYou've got "natural" in quotes there, but I honestly don't understand your intent. Do you think ternaries are unnatural? Do think they can't be used generate branchless code? Something else?
- tialaramex 4y agoThey can't be "used generate branchless code" because it's completely the wrong layer. It's like imagining that using negative integers instead of positive will make your CPU run cooler, or that using a for loop in your code instead of a while loop would get rid of the "hourglass" busy cursor in your program. The C or C++ programmer is writing programs for an entirely imaginary machine (the "abstract machine") and even on that imaginary machine the compiler is allowed to perform "as if" transformations which change what happens so long as you can't observe the difference in certain ways. You would need a language in which branchless was a specific category so that the language cares that you didn't write a branch and won't transform what you wrote into something with a branch in it. Neither C nor C++ are that language.
- zasdffaa 4y ago> even on that imaginary machine the compiler is allowed to perform "as if" transformations which change what happens Yeah, but beginner programmers won't be told that. I can imagine even quite advanced programmers may be amazed because many do well in industry without digging deeply into their tools (for better or worse, there's often no need). A few years ago I discovered that CPUs equally don't do what the code tells them - they do out-of-order to a shocking degree, have store forwarding and shadow registers (code writes a value x to register r1 doesn't mean x gets written to r1) etc. etc. and my jaw was hanging open. Nobody knows anything until they find out.
- tialaramex 4y agoIt's much worse than that, the CPU is stuck in the real world which is obliged to obey Mother Nature's laws despite the fact - especially at that scale - we find them unintuitive. The abstract machine can have intuitive behaviour because we choose how it works, a real machine not so much. For example, humans behave as though "universal time" is a thing, even if they know intellectually that this isn't so. The CPU has no choice though, there is and can only be local time. Events definitely happen in order locally but with no larger coherency. So if you have two CPU cores, those aren't the same location and they necessarily don't experience the same time. When writing a program with concurrency (e.g. threads), your C compiler emits machine code which, based on the author's understanding of the CPU documentation, will perform the necessary dance if you expressed that's what you wanted so that it seems there's a larger coherent sense of time. This is called Sequential Consistency. If you forgot to express that properly or you get it wrong, the C standard says your program has "Undefined Behaviour" because the machine code emitted does something which makes sense locally to each CPU core but may not make any sense to you at all. In general humans cannot reason successfully about what their program does in this situation anyway, it's just a complete head fuck, so the C decision to mark this "Undefined behaviour", anything could happen, is actually a reasonable one.
- puffoflogic 4y agoThis is not a correct explanation of why there is not a global order of memory operations on modern CPUs. It has nothing at all to do with the passage of time on different cores. Nothing.
- yxhuvud 4y agoYes, as I quoted the term from the commenter and the OP. Ternaries are not unnatural, but thinking that they would be any different to normal if-statements is a very unnatural thought to me.
- zasdffaa 4y agoBecause if (..) c = 1 else c = 2; will "obviously" map on to a branches whereas c = .. ? 1 : 2; "obviously" corresponds to a cmov. It's a natural mapping, if not necessarily correct mapping with more knowledge.
- IshKebab 4y agoWhy though? Ternary is always introduced as syntactic sugar for if/else.
- zasdffaa 4y agoMy K&R C book agrees with you, but there when you know about cmov, it seems to map cleanly to ?:. It's just my opinion and what I feel. I can't back it up any better.
- monocasa 4y agoBecause it's an single assignment expression dependent on a result that'll probably trivially be in a status flag.
- kzrdude 4y agoWhy not? It's expression oriented and as such seems to be a good way to write it.
- yxhuvud 4y agoUh, because it is just syntax sugar for an if-statement. And those are typically implemented using branches. There may be possible optimizations to make them branchfree in certain cases, but it is certainly not something I'd assume would be the default.
- samatman 4y agoBecause it's syntax which looks like an expression but isn't fully evaluated. That's unusual, C syntax is complex and new users are often very focused on figuring out pointers, you can miss that `= a() && b() || c();` always calls b and c but that `= a() ? b() : c();` only calls one of them depending on whether a is zero.
- chaosite 4y agoAm I missing something? && are || are short-circuiting operators in C, so in that example b and c won't always be called either.
- samatman 4y agoNo you're correct of course. I could go back and edit it to be & and |, but I think leaving the easy-for-a-noob to make mistake in actually illustrates the point better. It wasn't on purpose, my brain took a shortcut from the eager logical operators I work with more frequently.
- puffoflogic 4y agoWhat is shockingly common is people who comment without thinking. Nowhere in my comment did I imply that I thought the author of the original article held the position that I was critiquing. And yet you have decided to assume that I did imply that in order to create an opportunity to insult me, to get your internet kicks for the day I suppose.