c++ - 奇怪的 C++ 警告

标签 c++ bit-manipulation

源自 EDG 的某些编译器给我表达式无效警告 在这条线上

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编译器

最佳答案

我开始证明存在可以优化为常量的传递性;我不能。正如匿名者所指出的,先前的代码可以提供编译器用来将表达式退化为常量的约束。

但是,当有疑问时,打印真值表:

#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 视为不变的。编译器看起来要么非常聪明,要么就是坏了。

关于c++ - 奇怪的 C++ 警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3508824/

相关文章:

c++ - 上限固定时的操作顺序

hash - 如何在Go中实现HashCash的算法(类型转换问题)?

java - 在 C++ 和 Java 中只有一个返回值的原因是什么?

c - 如何使用二元运算高效地执行 ==?

c++ - 为什么我的循环只从我的 .obj 文件中读取一个字符?

c++ - 什么时候默认析构函数对类来说足够了?

c - 如何对大小/类型不同的变量执行按位比较

javascript - Javascript中位运算的效率

c++ - SearchPathW 卡住

c++ - 如何将我的程序指向我输入到列表中的值? C++