Hi, It seems to have some regression in gcc 4.3, visible on arm targets as well as x86_64. I originally already reported it to Debian bugtracking system [http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=472867] I tested it against the latest gcc snapshot: gcc (GCC) 4.3.1 20080501 (prerelease) gcc has been built with no option, only srcdir/configure && make. preprocessed content: # 1 "c.c" # 1 "<built-in>" # 1 "<command-line>" # 1 "c.c" extern void func(void*); void test() { register long *foo = (long*) 1024; register int index; for(index=0;index<1024;index++) func(foo--); } This is a simple loop indexed on an integer. It should be finite, but when compiling with -O2 (and -O3) the compiler removes the end condition. gcc -S -O2 extract: .LCFI0: movl $1024, %edi .p2align 4,,10 .p2align 3 .L2: leaq -8(%rdi), %rbx call func movq %rbx, %rdi jmp .L2 Note that when using char* or non-pointer type for foo variable, it compiles successfully.
Pointers types overflow is undefined which is what you are seeing.
shouldn't gcc report a warning in this case ? because silently entering an infinite loop is not very kind...
(In reply to comment #2) > shouldn't gcc report a warning in this case ? Maybe, but really depending on undefined behavior is bad too.
(In reply to comment #2) > shouldn't gcc report a warning in this case ? > > because silently entering an infinite loop is not very kind... > If your code invokes undefined behavior, how is gcc going to read your mind? Maybe the programmer meant to enter an infinite, so a warning isn't correct.
Now, this code should not rely on undefined behaviour: extern void func(int,void*); void test() { register long *foo = (long*) (4*sizeof(*foo)) - 1; register int index; for(index=0;index<4;index++) func(index,foo--); } it still make an infinite loop, while last func call is done with foo parameter (nil). Do you mean I explicitely ask gcc to use foo as end-of-loop condition ??
>Now, this code should not rely on undefined behaviour: It does because incrementing or decrementing to a NULL Pointer is undefined.
it's right, using --foo unstead of foo-- gives a better result. But it does not make me happy (about the possibility of a bug)
On some embedded machines, the SDRAM lays on 0x00000000 address. So it is not so meaningless to increment or decrement from/to NULL pointer.
decrementing a NULL pointer invokes undefined behavior, incrementing not.
*** Bug 36232 has been marked as a duplicate of this bug. ***
(In reply to comment #4) > If your code invokes undefined behavior, how is gcc going > to read your mind? If GCC can tell that it is undefined behavior, then warning the user is more useful than silently producing nasal demons, regardless of what might be in the user's mind. "The spec allows us to do something stupid" doesn't mean "we should do something stupid". > Maybe the programmer meant to enter > an infinite, so a warning isn't correct. If it's undefined behavior, then too bad, right? I have a really hard time seeing how one would derive such intent from the above code, though -- or imagining what GCC is doing that made it think that generating the code it does is a good idea.