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,978 of 243,242   
   Michael S to highcrew   
   UB or not UB? was: On Undefined Behavior   
   12 Jan 26 16:28:57   
   
   From: already5chosen@yahoo.com   
      
   On Thu, 1 Jan 2026 22:54:05 +0100   
   highcrew  wrote:   
      
   > 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!   
   >   
      
   On related note.   
      
      
   struct bar1 {   
     int table[4];   
     int other_table[4];   
   };   
      
   struct bar2 {   
     int other_table[4];   
     int table[4];   
   };   
      
   int foo1(struct bar1* p, int v)   
   {   
     for (int i = 0; i <= 4; ++i)   
       if (p->table[i] == v)   
         return 1;   
     return 0;   
   }   
      
      
   int foo2(struct bar2* p, int v)   
   {   
     for (int i = 0; i <= 4; ++i)   
       if (p->table[i] == v)   
         return 1;   
     return 0;   
   }   
      
   According to C Standard, access to p->table[4] in foo1() is UB.   
   [O.T.]   
   I want to use language (or, better, standardize dialect of C) in which   
   behavior in this case is defined, but I am bad at influencing other   
   people. So can not get what I want.   
   [/O.T.]   
      
   Now the question.   
   What The Standard says about foo2() ? Is there UB in foo2() as well?   
   gcc code generator does not think so.   
      
   	.file	"ub.c"   
   	.text   
   	.p2align 4   
   	.globl	foo1   
   	.def	foo1;	.scl	2;	.type   
   	32;	.endef .seh_proc	foo1   
   foo1:   
   	.seh_endprologue   
   	movl	$1, %eax   
   	ret   
   	.seh_endproc   
   	.p2align 4   
   	.globl	foo2   
   	.def	foo2;	.scl	2;	.type   
   	32;	.endef .seh_proc	foo2   
   foo2:   
   	.seh_endprologue   
   	leaq	16(%rcx), %rax   
   	addq	$36, %rcx   
   .L5:   
   	cmpl	%edx, (%rax)   
   	je	.L6   
   	addq	$4, %rax   
   	cmpq	%rcx, %rax   
   	jne	.L5   
   	xorl	%eax, %eax   
   	ret   
   	.p2align 4,,10   
   	.p2align 3   
   .L6:   
   	movl	$1, %eax   
   	ret   
   	.seh_endproc   
   	.ident	"GCC: (Rev8, Built by MSYS2 project) 15.2.0"   
      
   --- 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