The if
statement in the following sample comes from an old project I am trying to build again. I am sorry this is not a verifiable sample in the sense that it does not reproduce the error, it compiles fine by itself.
enum S { };
struct R {
S type, state;
double height;
};
int main ()
{
int rows;
S alive, rc;
double h;
R *r, *n;
// BEGIN
if ( (((r = n-1) ->type & rc) && h > r->height) ||
(((r = n+1) ->type & rc) && h > r->height) ||
(((r = n-rows)->type & rc) && h > r->height) ||
(((r = n+rows)->type & rc) && h > r->height) )
{
n->state = alive;
}
// END
}
However, within the project, with the same compilation (clang 3.3 with no options except include paths), it gives
warning: multiple unsequenced modifications to 'r' [-Wunsequenced]
(pointing to sub-expression r = n - 1
). The if
statement (marked between BEGIN-END
) is identical within the project, only the types of the variables may be different. The types defined here are only crude approximations, but I think they are not really relevant to the warning. I have been able to simplify the expression down to
if( (r = n) || (r = n) ) //...
while still reproducing the warning within the project.
My understanding is that there is a sequence point after the evaluation of the first operand of operators &&
, ||
(when not overloaded). So I cannot explain the warning.
If there are any ideas concerning the form of the expression regardless of types, that would help.
EDIT
Using Vaughn Cato's comments, I have also found that
if( ((r = n-1) ->type) || ((r = n+1) ->type) )
produces the warning, while
if( bool((r = n-1) ->type) || bool((r = n+1) ->type) )
does not. S
is in fact a class that mimics an enumeration, and has a custom underlying class. It has overloaded bitwise operators &
, |
and !
for masking, and implicit conversion operator to the underlying type, which in the particular case is size_t
. I don't know how much this helps, but I am sorry for not disclosing more complete information right from the start.