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

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

问题描述

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

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



我从[-Wsequence-point]收到此警告

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

我的g ++版本是4.4.5



我会感激谁解释这个简单的问题。



btw你可以在 this 中文网站(不必要)



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不知道如何评估语句表达式(不要与表达式语句混淆 - 这是应该最后出现在语句表达式中) 。



因此,为了防止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天全站免登陆