Re: [math-fun] min(x, y) and sorting without if()
From: Joerg Arndt <arndt@jjj.de>
* Phil Carmody <thefatphil@yahoo.co.uk> [Jan 07. 2012 11:41]:
From: Joerg Arndt <arndt@jjj.de>
These (branch-avoiding) techniques are "well known", see (fxtbook) section 1.11 "Avoiding branches", pp.15ff where a warning of the form "Your compiler may be smarter than you thought" is given.
Shouldn't the warning be more Nuddsian?
I do not parse "Nuddsian" here.
Pertaining to Scott Nudds, the troll/loon who managed to force us to turn comp.lang.asm.x86 into a moderated newsgroup back in the mid-90s. His name is certainly not forgotten on comp.lang.c either, as he was a notorious cross-poster (he would deliberately try to get the two camps to fight each other). One of his weapons was the invocation of ...
In C, such expressions are either unnecessary or UB, pure and simple.
Reading UB as "useless b*ll****":
"Undefined behaviour", as per the ISO C specification. In reality, it can equate to the same thing, as a sufficiently smart compiler can do exactly what you *don't* want in cases where UB is encountered. Many of the tricks are far from useless, but sometimes need a little bit of massaging before the C standard guarantees they will work.
There are a couple of tricks that prove useful in practice. E.g., replacing if ( (a<b) || (c<d) ) { ... } by if ( (a<b) | (c<d) ) { ... } can be an improvement.
Anything's possible. The latter has more re-ordering flexibility in some situations, so might fill bubbles in pipelines better. In reality, the programmer may not give a hoot which of the two comparisons expressions are evaluated first, but the short-circuit operator obliges him to express a preference.
One that I use regularly: Replace if ( (a<0) || (a>=n) ) { ... } by if ( (unsigned)a>=n ) { ... }
Yup, that type of trick is a good one and it's safe. I've even gone as far as subtracting a lower bound before doing that, and then comparing >= range rather than >= max.
Yes, there are assumptions made, but I am not aware of any _existing_ system where these do no hold.
They certainly do exist. I perhaps immerse myself in a wider range of architectures than most, both at work and at home, so I am more aware of them. Shifting sign bits around on some DSPs will cause mayhem. Some Crays have trap representations for certain types which mean you can't hold certain intermediate values that would be useful. Worse, arch's with separate address and integer registers lose some of the efficiency of Knuth's dancing links, for example, in particular if their AGU is slow.
Your compiler doesn't have to show smart behaviour at all - it may kill your cat if it wants to.
Haven't spotted the part about cat slaughter in the standard yet :-)
The problem is that it's not forbidden, so when the C standard says it imposes no restriction on what the implementation may do, that's implicitly giving it permission to kill kittens. The original absurd behaviour example was "nasal demons" (demons may fly out of your nose). That was hackneyed enough to have mutated to having the aforementioned Scott Nudds fly out of your nose. All such outcomes are to be avoided.
And quite a few people work extremely hard to make compilers smart.
That's one of the things that makes UB so dangerous. They can be so smart that they realise that certain inputs would lead to UB, and therefore they only have to generate the correct results for the inputs that don't lead to UB, no matter what the consequences are in the UB case. GCC being smart regarding being able to not care about what happens when there's UB has introduced security holes into the linux kernel. It can just throw away a null pointer check, for example: http://lwn.net/Articles/341773/ I seem to have deviated both from mathiness and funness here, I apologise. It's just that I live, eat and breathe strict portable C currently, in particular other people's, and I'm hypersensitive to anything which is UB. Phil
* Phil Carmody <thefatphil@yahoo.co.uk> [Jan 09. 2012 20:07]:
[...]
I seem to have deviated both from mathiness and funness here, I apologise. It's just that I live, eat and breathe strict portable C currently, in particular other people's, and I'm hypersensitive to anything which is UB.
Belatedly: I did very much appreciate this message! (sufficient appreciation == fun)
Phil
participants (2)
-
Joerg Arndt -
Phil Carmody