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,731 of 243,242    |
|    Andrey Tarasevich to highcrew    |
|    Re: On Undefined Behavior    |
|    03 Jan 26 07:53:22    |
   
   From: noone@noone.net   
      
   On Thu 1/1/2026 1:54 PM, highcrew wrote:   
   > Let's take an example. There's plenty here:   
   > https://en.cppreference.com/w/c/language/behavior.html   
   > So let's focus on https://godbolt.org/z/48bn19Tsb   
   >   
   > For the lazy, I report it here:   
   >   
   > int table[4] = {0};   
   > int exists_in_table(int v)   
   > {   
   > // return true in one of the first 4 iterations   
   > // or UB due to out-of-bounds access   
   > for (int i = 0; i <= 4; i++) {   
   > if (table[i] == v) return 1;   
   > }   
   > return 0;   
   > }   
   >   
   > This is compiled (with no warning whatsoever) into:   
   >   
   > exists_in_table:   
   > mov eax, 1   
   > ret   
   > table:   
   > .zero 16   
   >   
   >   
   > Well, this is *obviously* wrong.   
      
   Once again, one equivalent definition of undefined behavior is: "The   
   compiler is free to assume that conditions that lead to undefined   
   behavior never occur".   
      
   (And, as a corollary: if some stretch of code is always undefined,   
   regardless of external conditions, the compiler is free to assume that   
   the code is never executed.)   
      
   The above is exactly how undefined behavior is used for optimizing code   
   through static analysis.   
      
   On your case undefined behavior happens when `i` reaches 4. Hence the   
   compiler is free to assume that `i` is guaranteed to never reach 4. This   
   means that the `if` condition is guaranteed to become true at some lower   
   value of `i` (i.e. the compiler is free to assume that the calling code   
   made a promise to never pass a `v` that is not present in `table`). This   
   immediately means that the function will always return 1.   
      
   That's what you are observing.   
      
   > I understand the formalism: the resulting assembly is formally   
   > "correct", in that UB implies that anything can happen.   
      
   That's is true, but that is a very broad and general formalism. The   
   logic the compiler follows is not that broad or general. It is   
   significantly more focused on the properties of the actual code. The   
   compiler "deduces" the result as I described above.   
      
   --   
   Best regards,   
   Andrey   
      
   --- 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