Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why I got "operation may be undefined" in Statement Expression in C++?

to describe the problem simply, please have a look at the code below:

int main()
{
    int a=123;
    ({if (a) a=0;});
    return 0;
}

I got this warning from [-Wsequence-point]

Line 4: warning: operation on 'a' may be undefined

my g++ version is 4.4.5

I'll appreciate whoever would explain this simple problem.

btw you could find my original program and original problem in #7 in this Chinese site (not necessary)

UPD1:

though to change the code into ({if(a) a=0; a;}) can avoid the warning, but I recognized that the real reason of the problem may not be The last thing in the compound statement should be an expression followed by a semicolon.

because the documentary also said If you use some other kind of statement last within the braces, the construct has type void, and thus effectively no value.

an example can show it:

int main()
{
    int a=123, b;
    ({;});
    ({if (a) b=0;});
    return 0;
}

and this code got no warnings! so I think the real reason is something about sequence point.

please help!

UPD2:

sorry to @AndyProwl for having unaccept his answer which was accepted before UPD1. following his advise I may ask a new question (UPD1 is a new question different from the original one). I'll accept his answer again because it surely avoids warnings anyhow.:)

If I decided to ask a new question, I'll update this question to add a link.

like image 420
FLanS39 Avatar asked May 30 '13 14:05

FLanS39


1 Answers

According to the C++ grammar, expressions (apart from lambda expressions perhaps, but that's a different story) cannot contain statements - including block statements. Therefore, I would say your code is ill-formed, and if GCC compiles it, it means this is a (strange) compiler extension.

You should consult the compiler's reference to figure out what semantics it is given (or not given, as the error message seems to suggest) to it.

EDIT:

As pointed out by Shafik Yaghmour in the comments, this appears to be a GNU extension. According to the documentation, the value of this "statement expression" is supposed to be the value of the last statement in the block, which should be an expression statement:

The last thing in the compound statement should be an expression followed by a semicolon; the value of this subexpression serves as the value of the entire construct. (If you use some other kind of statement last within the braces, the construct has type void, and thus effectively no value.)

Since the block in your example does not contain an expression statement as the last statement, GCC does not know how to evaluate that "statement expression" (not to be confused with "expression statement" - that's what should appear last in a statement expression).

To prevent GCC from complaining, therefore, you should do something like:

({if (a) a=0; a;});
//            ^^

But honestly, I do not understand why one would ever need this thing in C++.

like image 128
Andy Prowl Avatar answered Oct 12 '22 03:10

Andy Prowl