奇怪的C ++警告

时间:2010-08-18 03:45:36

标签: c++ bit-manipulation

从EDG派生的某些编译器给出了expression has no effect警告 在这一行

return 1 << ((i == j) + (k == l) + ((i == k) & (j == l)));

值是运行时值,编译器不知道它们。

return 1 << (((i == k) & (j == l))); // no warning here
return 1 << ((i == j) + (k == l)); //or here

我错过了什么或编译器混淆了吗?

下面的代码段没有警告。 如果将参数更改为常量引用,则警告返回

    //static int symmetry(const int &i, const int &j, const int &k, const int &l) {
    static int symmetry(int i, int j, int k, int l) {
        // return 1 << ((i == j) + (k == l));
        //return 1 << (((i == k) && (j == l)) + (k != l));
        return 1 << ((i == j) + (k == l) + ((i == k) && (j == l)));
    }

即使有警告,程序也是正确的。程序错误的可能性非常小,这个特定的代码段会抛出计算

谢谢你的时间,我将假设编译器在这里犯了错误。 万一你发现类似的问题,编译器是nvcc,NVIDIA gpu cuda编译器

2 个答案:

答案 0 :(得分:4)

我开始证明存在可以针对常数进行优化的过渡性;我不能。正如匿名所述,先前的代码可以提供编译器用于将表达式简并为常量的约束。

但是,如果有疑问,请打印一个真值表:

#include <stdio.h>

int main() {
    int i, j, k, l, x;
    for(i = 0; i < 2; i++)
    for(j = 0; j < 2; j++)
    for(k = 0; k < 2; k++)
    for(l = 0; l < 2; l++) {
        x = ((i == j) + (k == l) + ((i == k) & (j == l)));
        printf("%d %d %d %d: %d, %d, %d -> %d\n", i, j, k, l, (i == j),
                (k == l), ((i == k) & (j == l)), x);
    }
    return 0;
}

哪个收益率:

0 0 0 0: 1, 1, 1 -> 3
0 0 0 1: 1, 0, 0 -> 1
0 0 1 0: 1, 0, 0 -> 1
0 0 1 1: 1, 1, 0 -> 2
0 1 0 0: 0, 1, 0 -> 1
0 1 0 1: 0, 0, 1 -> 1
0 1 1 0: 0, 0, 0 -> 0
0 1 1 1: 0, 1, 0 -> 1
1 0 0 0: 0, 1, 0 -> 1
1 0 0 1: 0, 0, 0 -> 0
1 0 1 0: 0, 0, 1 -> 1
1 0 1 1: 0, 1, 0 -> 1
1 1 0 0: 1, 1, 0 -> 2
1 1 0 1: 1, 0, 0 -> 1
1 1 1 0: 1, 0, 0 -> 1
1 1 1 1: 1, 1, 1 -> 3

在gcc和g ++ 4.4.3下,没有设置-Wall的警告。即使i,j,k和l声明为const,编译器也不会将x视为不变量。编译器似乎是超验智能的或者是破碎的。

答案 1 :(得分:1)

此表达式之前的代码是什么?

编译器可能在您的函数中找到优化,这意味着您的条件每次总是评估为相同的答案。听起来好像编译器告诉你你的逻辑在某处有缺陷而且你可以“返回0;”或“返回1;”具有相同的效果。