2

考虑以下代码:

$ cat o.c 
#include <stdio.h>
#include <limits.h>

int absolute(int i) {
  int j = i < 0 ? -i : i;
  if (j<0)      /* This is line 6 */
    return 0;
  return j;
}

int main() {
  int i = 1;
  printf("%d %d\n", i, absolute(i));
  return 0;
}

编译它-O2-Wstrict-overflow产生警告:

$ gcc -O2 -Wall -Wextra -Wstrict-overflow o.c 
o.c: In function ‘absolute’:
o.c:6:6: warning: assuming signed overflow does not occur when simplifying comparison of absolute value and zero [-Wstrict-overflow]

现在考虑以下在功能上与上述代码等效的代码:

$ cat p.c 
#include <stdio.h>
#include <limits.h>

int main() {
  int i = 1;
  int j = i < 0 ? -i : i;
  if (j<0) // Changing i to INT_MIN above and changing (j<0) to (j>INT_MAX)
           // doesn't change the behavior
    j=0;
  printf("%d %d\n", i, j);
  return 0;
}

使用相同的选项编译它不会导致任何警告。

$ gcc -O2 -Wall -Wextra -Wstrict-overflow p.c 
$

如第二个代码中所述,将分配更改为i=INT_MIN;和条件更改为(j>INT_MAX)也不会发出警告。

我在 Ubuntu 上使用 gcc 4.7.2:

$ gcc --version
gcc (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2

我无法弄清楚这两种情况的区别。它与优化有关还是 gcc 在这里表现不佳?

4

2 回答 2

8
于 2013-07-22T10:57:05.237 回答
2

In the first program the optimizer recognizes the sign of an absolute value is checked with a variable argument not known at compile time.

In the second program, the value of i is known and the result of j and j < 0 are computed at compile time before any further optimizations like the one used in the first program.

A good way to get convinced of this is to change the value of i in the second program to something known only at run-time:

int i = 1 + printf(""); // 1 if no error, cannot be deduced
                        // at compile time
int j = i < 0 ? -i : i;
if (j<0) 

would get you the same warning as in the first program when compiled with -O2 -Wstrict-overflow.

于 2013-07-22T11:09:04.813 回答