简体   繁体   English

为什么在C ++的语句表达式中出现“操作可能不确定”的信息?

[英]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] 我从[-Wsequence-point]得到了这个警告

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

my g++ version is 4.4.5 我的g ++版本是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) 顺便说一句,您可以在中文站点的#7中找到我的原始程序和原始问题(没有必要)

UPD1: 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 . 虽然改变的代码到({if(a) a=0; a;})可避免警告,但我认识到了问题的真正的原因可能并不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 . 因为纪录片还说, 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: UPD2:

sorry to @AndyProwl for having unaccept his answer which was accepted before UPD1. 抱歉@AndyProwl未能接受UPD1之前接受的答案。 following his advise I may ask a new question (UPD1 is a new question different from the original one). 按照他的建议,我可能会问一个新问题(UPD1是一个与原始问题不同的新问题)。 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. 根据C ++语法,表达式(也许除了lambda表达式之外,但这是另一回事)不能包含语句-包括块语句。 Therefore, I would say your code is ill-formed, and if GCC compiles it, it means this is a (strange) compiler extension. 因此,我想说您的代码格式错误,如果GCC对其进行编译,则意味着这是(奇怪的)编译器扩展。

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. 正如Shafik Yaghmour在评论中指出的那样 ,这似乎是GNU扩展。 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.) (如果最后在花括号内使用其他类型的语句,则该构造的类型为void,因此实际上没有任何值。)

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). 由于示例中的块不包含表达式语句作为最后一个语句,因此GCC不知道如何评估该“语句表达式”(不要与“表达式语句”相混淆-这就是应该在语句表达式中最后出现的内容) 。

To prevent GCC from complaining, therefore, you should do something like: 因此,为防止GCC投诉,您应该执行以下操作:

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

But honestly, I do not understand why one would ever need this thing in C++. 但老实说,我不明白为什么在C ++中会需要这个东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM