[HN Gopher] Undefined Isn't Unpredictable
       ___________________________________________________________________
        
       Undefined Isn't Unpredictable
        
       Author : ingve
       Score  : 42 points
       Date   : 2022-11-07 14:23 UTC (8 hours ago)
        
 (HTM) web link (www.os2museum.com)
 (TXT) w3m dump (www.os2museum.com)
        
       | mnw21cam wrote:
       | The problem with redefining instructions to now give defined
       | results where before they were undefined is that software
       | developers might start relying on that defined behaviour, but
       | CPUs from other manufacturers and emulators might still give
       | undefined behaviour. Of course, Intel might not care about that.
       | 
       | Once something has been declared undefined, there is a barrier to
       | changing it to defined, just as much as changing it in the
       | opposite direction.
        
         | dale_glass wrote:
         | Could be worse!
         | 
         | I vaguely recall a recent C or C++ standard declaring something
         | UB that wasn't UB before. Kinda hard to search for though, so
         | the exact case so far eludes me.
        
           | jcranmer wrote:
           | In general, most of the times when something "newly" becomes
           | UB, it was already UB in practice. The most obvious case was
           | the C11/C++11 definition of INT_MIN % -1 to be UB (as
           | everyone tends to implement % as part of a combined / and %
           | instruction, and INT_MIN / -1 is clearly UB).
        
       | keybored wrote:
       | > The bottom line is that it is very wrong to understand
       | "undefined" in this context as "random", and even taking it to
       | mean "unpredictable" is at best misleading.
       | 
       | See also: arbitrary _contra_ random.
        
       | [deleted]
        
       | symmetricsaurus wrote:
       | The situation in C++ is similar. With a particular compiler and
       | with a specific set of compilation flags you can sometimes get
       | predictable behavior even if it's undefined (and sometimes not).
       | But, there are no guarantees and if you change compiler, flags or
       | perhaps even some other part of the code the behavior can change.
       | 
       | Perhaps with out of order CPUs relying on something that is
       | undefined could change based on adjacent instructions also?
        
         | Conscat wrote:
         | There's one big difference between undefined behavior in C and
         | C++. In C++, undefined behavior is ill-formed when it is
         | constant-evaluated. And for aspects which are tricky to
         | determine undefined behavior for, such as reinterpret_cast or
         | type-punning in a union, they're just disallowed in constexpr
         | code entirely. So in C++, you can't necessarily just say "well
         | this is undefined, but it works correctly within our particular
         | constraints", whereas you always can say that in C. That makes
         | implementation-defined a huge difference from undefined. You
         | can always cast signed integers to unsigned integers or vice
         | versa in constexpr code.
        
         | pornel wrote:
         | In case of a CPU it's safer, because the existing hardware
         | definitely won't change, and you can hope the vendor won't do
         | anything drastic in microcode updates.
         | 
         | But UB in a language with an optimizer is a bigger gamble. Even
         | changes to code _outside_ of your UB-tainted function may trip
         | inlining and hot code heuristics, which may make more or less
         | of the code visible to the optimizer, which may make it take
         | advantage of different  "undefined" assumptions.
        
         | Mathnerd314 wrote:
         | It's not similar at all. It used to be C operations mapped 1-1
         | to the hardware, so undefined behavior meant unspecified but
         | well-behaved in the sense that it would not randomly change
         | unrelated registers. Now it means "nasal demons", i.e. the
         | compiler can just ignore any execution path with undefined
         | behavior and eliminate it as dead code.
        
           | Mathnerd314 wrote:
           | For more, see https://www.complang.tuwien.ac.at/kps2015/proce
           | edings/KPS_20... (clearly distinguishing "C*" which
           | corresponds to the hardware from "C" which is the subset of
           | C[?] that excludes all undefined behaviour) and
           | https://arxiv.org/pdf/2201.07845.pdf "How ISO C became
           | unusable for operating systems development".
        
       | zajio1am wrote:
       | The meaning depends on context. In hardware, it is common to
       | depend on 'undefined', but stable and predictable behavior. In
       | case of C standard, there is separate 'undefined' and
       | 'unspecified' (and also 'implementation-defined'). And
       | 'undefined' is allowed to be unpredictable and inconsistent,
       | because it is just invalid usage.
        
       ___________________________________________________________________
       (page generated 2022-11-07 23:01 UTC)