home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c      Meh, in C you gotta define EVERYTHING      243,242 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 242,791 of 243,242   
   David Brown to highcrew   
   Re: On Undefined Behavior   
   05 Jan 26 15:39:28   
   
   From: david.brown@hesbynett.no   
      
   On 04/01/2026 12:51, highcrew wrote:   
   > On 1/4/26 2:10 AM, Paul J. Lucas wrote:   
   >> This particular example is explained is several places, e.g.:   
   >>   
   >> https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=633   
   >>   
      
   At a cursory read, that article looks okay.  The lesson to learn is   
   "look before you leap" - don't use data if you are not sure it is valid,   
   and certainly don't add new uses of the data (such as debug prints) just   
   before validity checks!   
      
   It does, however, perpetuate the myth that there is a clear distinction   
   between "classical compilers" or "non-optimising compilers" and   
   "optimising compilers".  That is not true - for any two standards   
   conforming compilers (or selection of flags for the same compiler), the   
   same source code is equally defined or undefined.  Source code with UB   
   has UB whether it is "optimised" or not, though the colour of the   
   resulting nasal daemons may vary.   
      
      
   >> Perhaps a slightly better explanation of the same example:   
   >>   
   >> https://medium.com/@pauljlucas/undefined-behavior-in-c-and-c-f30844f20e2a   
   >>   
      
   That one starts off with a bit of a jumble of misconceptions.   
      
      
   To start with, "undefined behaviour" does not exist because of   
   compatibility issues or the merging of different C variations into one   
   standard C.  It is a fundamental principle in programming because many   
   computing functions are, mathematically, partial functions - they can   
   only give a sensible defined result for some inputs.  While it can   
   sometimes be possible to verify the validity of inputs, it is often   
   infeasible or at least very costly, especially in non-managed (compiled)   
   languages.  Pointer dereference, for example, only has defined behaviour   
   if the pointer points to a valid object - otherwise the result is   
   meaningless (even if some assembly code can be generated).  Garbage in,   
   garbage out - see the Babbage quotation.   
      
   The C standard is simply somewhat unusual in that it is more explicit   
   about UB than many languages' documentation.  And being a language   
   intended for maximally efficient code, C leaves a number of things as UB   
   where other languages might throw an exception or have other error handling.   
      
   The definition given for "implementation defined behaviour" and   
   "unspecified behaviour" is poor.  (IMHO the comp.lang.c FAQ is   
   inaccurate here.)  In particular, "unspecified behaviour" does not need   
   to be consistent.  For example, the order of evaluation of function   
   arguments is unspecified, and can be done in different orders at   
   different call sites - even in identical source code.  It can even be   
   re-ordered between different invocations of the same code - perhaps due   
   to complicated inter-procedural optimisations, inlining, code cloning,   
   and constant propagation.   
      
   It then goes on to say that the order of evaluation of the operands of   
   "+" are implementation defined, when it is in fact a good example of   
   unspecified behaviour that is /not/ implementation defined.   
      
   Implementation defined behaviour is /not/ "bad" - pretty much all   
   programs rely on implementation-defined behaviour such as the size of   
   "int", character sets used, etc.  Relying on implementation-defined   
   behaviour reduces the portability of code, but that is not necessary a   
   bad thing.   
      
   And while it is true that UB is "worse" than either   
   implementation-defined behaviour or unspecified behaviour, it is not for   
   either of the reasons given.  The *nix program "date" does not need to   
   contain UB in order to produce different results at different times.   
      
      
   The examples of UB, and the consequences of them, are better.   
      
   It also makes the mistake common in discussions of UB optimisations of   
   concluding that the optimisation makes the code "wrong".  Optimisations,   
   such as the example of the "assign_not_null" function, are "logically   
   valid" and /correct/ from the given source code.  Optimisations have not   
   made the code "wrong", nor has the compiler.  The source code is correct   
   for a given validity subset of its parameter types, and the object code   
   is correct for that same subset.  If the source code is intended to work   
   over a wider range of inputs, then it is the source code that is wrong -   
   not the optimiser or the optimised code.   
      
      
   >> - Paul   
   >   
   > Hey, thanks for the pointers.   
   > I found the second a really good write up!   
   >   
      
   I've seen worse, but it could be better.   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca