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

> C++ should clearly have picked Unspecified Behaviour rather than Undefined Behaviour but too late now.

Why is it too late? Changing it in a later version of the standard wouldn't be a further constraint on any written code; any code which is currently correct will remain correct, and some code which could have done literally anything will now only be able to have one of a few possible behaviours.



The shift instruction is defined differently depending on the ISA. For example, on some CPUs "x >> 32 == 0" and on others "x >> 32 == x". Both shift designs are reasonable and C has to accommodate both. Defining this case would require putting a branch instruction in front of the shift instruction on many architectures. Obviously this would be a large performance regression.

Consider how long it took C++ to deprecate support for integers that are not two's complement, when every piece of silicon for many decades has been a two's complement design. In the case of shift instructions, it is defined differently across ISAs used today.


That is not a good pro argument.

When this operation is undefined, you must always put a branch instruction in front of it, on any architecture, regardless if it happens to do what you want.

Even when you know precisely the type of CPU on which the program will be run, you would need to use inline assembly to be sure of the behavior of the program.

When you can guarantee that the operand will never have the undesired value, then no branch instruction would be used on any architecture, regardless how the C standard would define the operation.

It is always better when the programming language standard defines completely all operations.

In the worst case, when two possible operation definitions are widespread in hardware implementations, two distinct operations should be defined in the language, allowing the programmer to choose the one that is more efficient on the intended target, but knowing that the program will remain correct regardless for which target it is compiled.


Why would having the standard set the behaviour as "unspecified" (or "implementation-defined") require a branch?

Surely under those circumstances, the compiler can document doing whatever the target ISA does as its behaviour, and just output the shift as-is?


I suppose it would break any currently compliant C++ compiler for which the target platform's CPU will throw an exception (or even less likely, return a random number) when shifting by a full word.

But I'd also suppose there aren't many such CPUs. Does anyone know of any?


> I suppose it would break any currently compliant C++ compiler

Maybe not?

I'm pretty sure that "trap" is an allowed behaviour for NaNs in some parts of the standard already, if properly documented. I don't see why unspecified/implementation-defined behaviour for shifts couldn't be allowed to do the same, on appropriate targets?

But also, the new behaviour should only be required of compilers in the to-be-written `--std=c++3X` (or whatever) mode. Any compilers conforming to an earlier version of the standard can already do whatever they're currently doing.




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

Search: