为什么我得到“操作可能未定义”在C ++语句表达式中? [英] Why I got "operation may be undefined" in Statement Expression in C++?

查看:537
本文介绍了为什么我得到“操作可能未定义”在C ++语句表达式中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

我从[-Wsequence-point]得到这个警告

 行4:警告:对'a'的操作可能未定义

我的g ++版本是4.4.5



我会欣赏谁能解释这个简单的问题。



btw您可以在这个中文网站(不需要)



UPD1:



虽然将代码更改为({if(a)a = 0; a;})可以避免警告,但我认识到真正的原因该问题可能不是复合语句中的最后一件事情应该是一个表达式,后跟一个分号



因为纪录片还表示如果您在大括号中使用其他类型的语句,则该构造的类型为void,因此无效值



一个例子可以显示:

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

,此代码已经没有警告
所以我认为真正的原因是关于序列点。



请帮助!



strong> UPD2:



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



如果我决定提出一个新的问题,我会更新这个问题来添加一个链接

解决方案

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



你应该参考编译器的参考找出它给出的语义(或者没有给出错误信息似乎建议)。



编辑: p>

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


复合语句中的最后一项应该是一个表达式,后跟一个分号;该子表达式的值用作整个构造的值。 (如果您在大括号中使用其他类型的语句,则该构造的类型为void,因此无效)。


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



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

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

但老实说,我不明白为什么会需要这个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.

解决方案

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++.

这篇关于为什么我得到“操作可能未定义”在C ++语句表达式中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆