views:

160

answers:

2

certain compiler, derived from EDG gives me expression has no effect warning on this line

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

values are runtime values, compiler does not know them.

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

am I missing something or is compiler confused?

the code segment below does not have warning. if a change parameters to constant reference, warning come back

    //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)));
    }

the program is correct even with warning. possibility that program is wrong is very very small this particular code segment would throw calculations off

thank you for your time, I am going to assume compiler is making mistake here. just in case you find similar problem, compiler is nvcc, NVIDIA gpu cuda compiler

+1  A: 

What is the code before this expression?

The compiler could be finding an optimisation in your function that means your condition always evaluates to the same answer each time. It sounds like the compiler is telling you that your logic is flawed somewhere and you could just "return 0;" or "return 1;" to have the same effect.

anonymous
We need to know how the funtion is being called. If it's being inlined within a different section of your code and you've set i = j = k = l in that context, the function will be optimized out completely.Can you give us a copy of the "by reference" function which does generate the warning?
anonymous
thanks for your time. I think I am just going to assume compiler is making a mistake in judgment from others people feedback
aaa
+4  A: 

I started to prove that there were transitivities that could be optimized to constants; I couldn't. As anonymous noted, the prior code could provide constraints that the compiler uses to degenerate the expressions to constants.

But, when in doubt, print a truth table:

#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;
}

Which yields:

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

Under both gcc and g++ 4.4.3 and no warnings with -Wall set. Even with i, j, k, and l declared const, the compiler doesn't see x as invariant. The compiler seems either transcendentally smart or is broken.

msw
Jonathan Leffler
transcendentally smart compilers would be super cool :)
obelix
msw
thank you. for time being I am going to assume compiler is broken/overly cautious.I am able to defeat warnings, and it is good enough for me
aaa
+1 for showing how to test.
Dummy00001