为什么我在C++中的Statement Expression中得到"操作可能未定义"?

FLa*_*S39 14 c++ expression sequence-points

简单描述问题,请看下面的代码:

int main()
{
    int a=123;
    ({if (a) a=0;});
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我收到了[-Wsequence-point]的警告

Line 4: warning: operation on 'a' may be undefined
Run Code Online (Sandbox Code Playgroud)

我的g ++版本是4.4.5

无论谁解释这个简单的问题,我都会感激不尽.

顺便说一句,你可以在这个中文网站的#7中找到我的原始程序和原始问题(不是必需的)

UPD1:

虽然改变代码({if(a) a=0; a;})可以避免警告,但我认识到问题的真正原因可能不是The last thing in the compound statement should be an expression followed by a semicolon.

因为纪录片还说If you use some other kind of statement last within the braces, the construct has type void, and thus effectively no value.

一个例子可以显示它:

int main()
{
    int a=123, b;
    ({;});
    ({if (a) b=0;});
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这段代码没有警告!所以我认为真正的原因是序列点.

请帮忙!

UPD2:

很抱歉@AndyProwl没有接受他在UPD1之前接受的回答.按照他的建议,我可能会问一个新问题(UPD1是一个与原始问题不同的新问题).我会再次接受他的回答,因为无论如何它肯定会避免警告.:)

如果我决定提出新问题,我会更新此问题以添加链接.

And*_*owl 5

根据C++语法,表达式(除了lambda表达式,但这是一个不同的故事)不能包含语句 - 包括块语句.因此,我会说你的代码格式不正确,如果GCC编译它,这意味着这是一个(奇怪的)编译器扩展.

您应该参考编译器的参考,以确定它给出的语义(或者没有给出,如错误消息似乎暗示的那样).

编辑:

正如Shafik Yaghmour在评论中指出的那样,这似乎是一个GNU扩展.根据文档,这个"语句表达式"的值应该是块中最后一个语句的值,它应该是一个表达式语句:

复合语句中的最后一件事应该是一个后跟分号的表达式; 此子表达式的值用作整个构造的值.(如果你在大括号中最后使用了一些其他类型的语句,那么构造的类型为void,因此实际上没有值.)

由于示例中的块不包含表达式语句作为最后一个语句,因此GCC不知道如何评估该"语句表达式"(不要与"表达式语句"混淆 - 这应该是在语句表达式中最后出现的内容) .

因此,为防止GCC抱怨,您应该执行以下操作:

({if (a) a=0; a;});
//            ^^
Run Code Online (Sandbox Code Playgroud)

但老实说,我不明白为什么人们会在C++中需要这个东西.

  • 这是一个gcc扩展:http://stackoverflow.com/questions/3079721/are-statement-and-declarations-in-expressions-specific-to-gnu-c虽然文档是最小的:http:// gcc. gnu.org/onlinedocs/gcc/Statement-Exprs.html ...我希望H2C03会详细说明他的评论. (2认同)