现代编译器是否在for循环中优化unsigned int的使用?

时间:2015-03-22 12:07:32

标签: c++ c compilation unsigned-integer

请考虑以下代码:

for(unsigned i = 0; i < counter1; i++) {
    for(unsigned j = 0; j < counter2; j++) {
        // some code here
    }
}

在此上下文中使用unsigned int而不仅仅是int有什么好处吗?现代编译器会以某种方式对其进行优化,还是唯一的好处就是unsigned int的较大尺寸?

2 个答案:

答案 0 :(得分:9)

unsigned int的for循环中使用int没有任何优势。使用unsigned int的数字范围内的边际收益远远超过引入错误的机会。此外,unsigned int使可读性更难。

可能引入错误的一个有趣案例是

for (unsigned int i = foo.Length()-1; i >= 0; --i) ...

您可能会注意到,此循环永远不会结束。一些现代gcc编译器可能会在这种情况下提供警告,但有时他们不会。在比较signedunsigned值时也会出现一些错误。如果您需要额外的空间,最好使用long代替unsigned int

特别是在讨论unsigned int的编译器优化时,没有任何收益。

答案 1 :(得分:1)

这些循环的编译器结果没有区别,因为在汇编中,除了比较之外,在大多数情况下,无符号整数的处理方式不同。然而,错误therainmaker mentions在其他情况下是相关的。

$ cat test.c
#include <stdlib.h>
#include <stdio.h>

int main(void) {
    unsigned buffer[100][100];

    for (unsigned i = 0; i < 100; i++) 
        for (unsigned j = 0; j < 100; j++)
            fprintf(stdout, "i");
}
$ sed s/unsigned/int/ test.c  > testint.c
$ gcc -std=c11 -O3 testint.c -S; gcc -std=c11 -O3 test.c -S
$ diff test.s testint.s
1c1
<   .file   "test.c"
---
>   .file   "testint.c"

如果我使用-O0,您会在分支时看到差异:

$ diff test.s testint.s
1c1
<   .file   "test.c"
---
>   .file   "testint.c"
27c27
<   jbe .L4
---
>   jle .L4
31c31
<   jbe .L5
---
>   jle .L5