From: 046-301-5902@kylheku.com   
      
   On 2026-01-09, Michael S wrote:   
   > On Fri, 09 Jan 2026 01:42:53 -0800   
   > Tim Rentsch wrote:   
   >   
   >> highcrew writes:   
   >>   
   >> > Hello,   
   >> >   
   >> > While I consider myself reasonably good as C programmer, I still   
   >> > have difficulties in understanding undefined behavior.   
   >> > I wonder if anyone in this NG could help me.   
   >> >   
   >> > 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. And sure, so is the original code,   
   >> > but I find it hard to think that the compiler isn't able to notice   
   >> > it, given that it is even "exploiting" it to produce very efficient   
   >> > code.   
   >> >   
   >> > I understand the formalism: the resulting assembly is formally   
   >> > "correct", in that UB implies that anything can happen.   
   >> > Yet I can't think of any situation where the resulting assembly   
   >> > could be considered sensible. The compiled function will   
   >> > basically return 1 for any input, and the final program will be   
   >> > buggy.   
   >> >   
   >> > Wouldn't it be more sensible to have a compilation error, or   
   >> > at least a warning? The compiler will be happy even with -Wall   
   >> > -Wextra -Werror.   
   >> >   
   >> > There's plenty of documentation, articles and presentations that   
   >> > explain how this can make very efficient code... but nothing   
   >> > will answer this question: do I really want to be efficiently   
   >> > wrong?   
   >> >   
   >> > I mean, yes I would find the problem, thanks to my 100% coverage   
   >> > unit testing, but couldn't the compiler give me a hint?   
   >> >   
   >> > Could someone drive me into this reasoning? I know there is a lot   
   >> > of thinking behind it, yet everything seems to me very incorrect!   
   >> > I'm in deep cognitive dissonance here! :) Help!   
   >>   
   >> The important thing to realize is that the fundamental issue here   
   >> is not a technical question but a social question. In effect what   
   >> you are asking is "why doesn't gcc (or clang, or whatever) do what   
   >> I want or expect?". The answer is different people want or expect   
   >> different things. For some people the behavior described is   
   >> egregiously wrong and must be corrected immediately. For other   
   >> people the compiler is acting just as they think it should,   
   >> nothing to see here, just fix the code and move on to the next   
   >> bug. Different people have different priorities.   
   >>   
   >   
   > I have hard time imagining sort of people that would have objections in   
   > case compiler generates the same code as today, but issues diagnostic.   
      
   If false positives occur for the diagnostic frequently, there   
   will be legitimate complaint.   
      
   If there is only a simple switch for it, it will get turned off   
   and then it no longer serves its purpose of catching errors.   
      
   There are all kinds of optimizations compilers commonly do that could   
   also be erroneous situations. For instance, eliminating dead code.   
      
    // code portable among several types of systems:   
      
    switch (sizeof var) {   
    case 2: ...   
    case 4: ...   
    case 8: ...   
    }   
      
   sizeof var is a compile time constant expected to be 2, 4 or 8 bytes.   
   The other cases are unreachable code.   
      
   Suppose every time the compiler eliminates unreachable code, it   
   issues a diagnostic "foo.c:42: 3 lines of unreachable code removed".   
      
   That would be annoying when the programmer knows about dead code   
   elimination and is counting on it.   
      
   We also have to consider that not all code is written directly by hand.   
      
   Code generation techniques (including macros) can produce "weird" code   
   in some of their corner cases. The code is correct, and it would take   
   more complexity to identify those cases and generate more idiomatic   
   code; it is left to the compiler to clean up.   
      
   --   
   TXR Programming Language: http://nongnu.org/txr   
   Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal   
   Mastodon: @Kazinator@mstdn.ca   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|