He Who Gives Up Correctness for Performance Deserves Neither
gavinhoward.com
gavinhoward.com
I don't think I've ever been the recipient of a diss track before. Here I'm called a Useful Idiot. Other folks can read the thread if they want.
The primary difference however is that say VHDL's std_ulogic type explicitly encodes what is considered undefined behaviour in C such as accessing uninitialised memory. So called U and X propagation turns expressions that depend on uninitialised values into U and X respectively. This means that your simulation tells you where the undefined behaviour is lurking. You can still synthesize your buggy hardware, nobody is stopping you, but it's not hidden.
Meanwhile with C you get into the "when did you stop beating your wife" scenario, where you are assumed guilty until proven innocent.
Whereas when hardware goes wrong, usually people deal with it like any faulty product.
Specifically how calculating an int aka signed 32 bit integer index was more performent than calculating a uint aka unsigned 32 bit integer index.
Because the former because an assembly intrinsic and the later can't because uint wraps at 32 bits not 64 bits.
So whether you choose wrapping or UB you are going to piss somebody off.
After all everybody wants the intrinsic. After all you are triggering UB anywhere the wrapping matters.
The reality is the number of similar UB based optimisations has grown considerably and even divesting of them would involve likely close to a man-decade worth of effort (unless you just discarded all of those performance improvements).
Correct code looks something like write the thing in a theorem prover, where it mostly suffers existentially.
So give you can't/won't write correct code, all you have is a Pareto surface denoted by performance and correctness aspects, and the distance between what you're shipping and that bounding optimum.
While you are technically correct, the key is your own statement:
> where it mostly suffers existentially.
Yes, theorem provers exist, and they work. But proving that the end result, the actual machine code, corresponds to the proven code, is the big problem.
When I talk about correctness in the post, I'm really referring to two things:
1. Correctness as you have defined it,
2. The compiler artifact being as faithful as possible to the input source code.
Avoiding UB is an excellent way to improve the latter.
I had no idea it was a thing that could be debated or changed, very interesting.