Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

for(i=0;i<10000000000;++i) compiles to endless loop?

I was running some tests to see how ++i and i++ translated to asm. I wrote a simple for :

int main()
{
    int i;
    for(i=0;i<1000000;++i);
    return 0;
}  

compiled it with gcc test.c -O0 -o test, and checked the asm with objdump -d test:

4004ed: 48 89 e5                mov    %rsp,%rbp
4004f0: c7 45 fc 00 00 00 00    movl   $0x0,-0x4(%rbp)  // i=0;
4004f7: eb 04                   jmp    4004fd <main+0x11>
4004f9: 83 45 fc 01             addl   $0x1,-0x4(%rbp)     // ++i;
4004fd: 81 7d fc 3f 42 0f 00    cmpl   $0xf423f,-0x4(%rbp) // 
400504: 7e f3                   jle    4004f9 <main+0xd>   //i<1000000;
400506: b8 00 00 00 00          mov    $0x0,%eax
40050b: 5d                      pop    %rbp
40050c: c3                      retq 

so far so good. The weird thing (if i understand asm code correctly) was when instead of i<1000000 i wrote i<10000000000. Exactly same for loop with stopping condition i<10000000000 translated to following assembler code :

4004ed: 48 89 e5                mov    %rsp,%rbp
4004f0: c7 45 fc 00 00 00 00    movl   $0x0,-0x4(%rbp)
4004f7: 83 45 fc 01             addl   $0x1,-0x4(%rbp)
4004fb: eb fa                   jmp    4004f7 <main+0xb>

which is endless loop per my understanding, cause exactly same asm was generated for :

 for(i=0;;++i);

The question is, is it really possible that it is compiled to endless loop? Why? I'm using Ubuntu 13.04, x86_64.

Thanks.

like image 628
Dabo Avatar asked Jan 19 '14 14:01

Dabo


1 Answers

This happens because the maximum value of an int on your architecture can never reach 10000000000. It will overflow at some point before reaching that value. Thus, the condition i < 10000000000 will always evaluate as true, meaning this is an infinite loop.

The compiler is able to deduct this at compile time, which is why it generates appropriate assembly for an infinite loop.

The compiler is able to warn you about this. For that to happen, you can enable the "extra" warning level with:

gcc -Wextra

GCC 4.8.2 for example will tell you:

warning: comparison is always true due to limited range of data type [-Wtype-limits]
for (i = 0; i < 10000000000; ++i);
^

And it even tells you the specific warning option that exactly controls this type of warning (Wtype-limits).

like image 158
Nikos C. Avatar answered Oct 05 '22 02:10

Nikos C.