C++ 以下程序的意外输出

C++ 以下程序的意外输出,c++,pointers,C++,Pointers,输出生成了6 11,为什么不在执行步骤上提供6 12指南呢。 这里我的疑问是**p只指向x,它由第二个操作数+++**p递增。所以y的值应该是12 这是典型的未定义行为!在C++标准中,在Y= **P++**P.中+运算符的操作数的评价顺序没有保证。 我在MSVC和clang cl中测试了您的代码,得到的结果是:6 12-这表明,正如您所期望的那样,++**p首先被计算。然而,在编译器上,似乎LHS是首先计算的 从Scheff评论中链接的CPPPreference站点: 任何表达式任何部分的求值

输出生成了6 11,为什么不在执行步骤上提供6 12指南呢。 这里我的疑问是**p只指向x,它由第二个操作数+++**p递增。所以y的值应该是12

这是典型的未定义行为!在C++标准中,在Y= **P++**P.

中+运算符的操作数的评价顺序没有保证。 我在MSVC和clang cl中测试了您的代码,得到的结果是:6 12-这表明,正如您所期望的那样,++**p首先被计算。然而,在编译器上,似乎LHS是首先计算的

从Scheff评论中链接的CPPPreference站点:

任何表达式任何部分的求值顺序,包括求值顺序 函数参数的计算未指定,但有一些例外 如下所列。编译器可以计算操作数和其他值 子表达式的任何顺序,并且在 再次计算相同的表达式。不存在任何概念 在C++中,从左到右或从右到左的评价……/P>
PS:有趣的是,改为y=++**p++**p;也给出6 12作为输出。

y=**p++**p;等于11。括号中没有歧义。原来的5,x变成了6,剩下的旧值已经被读取,即5。5+6=11@John您似乎假设+的左侧肯定会首先被计算。cppreference.com上有一个额外的部分列出了您的示例:n=++i+i;//未定义的行为。在你的例子中,i是**p不会改变任何东西。这可能是不在表达式中嵌入赋值的一个原因。如果一个术语的值必须在表达式中更改,则拆分表达式并在两者之间进行所需的更改。Ppl倾向于错误地认为密集的源代码会产生密集或高效的执行。这通常是错误的过早优化,可能会产生副作用,或者这里有未定义的行为。@Scheff-我有点同意。关键是,两个不同的编译器给出了两个不同的答案,所以这是未定义的行为!这还不够笼统。同一个编译器可以在同一个二进制文件中自由给出两个不同的答案,并且没有任何明显的原因。这就是为什么没有定义的行为。你建议的是实现定义的行为,但事实并非如此。一旦你用新版本的编译器重新编译了一个程序,它突然崩溃了,而忽略了一个事实,即它已经成功销售并被客户使用多年了-你开始像我一样害怕未定义的行为这样的经验将理论上的关注转移到日常业务中——非常实际。关于不同的编译器:,但请注意gcc的种类:
#include<iostream>
#include<conio.h>
using namespace std;
int main()
{

     int y,**p,*pt;
     int x=5;
     pt=&x;
     p=&pt;
     y=**p + ++(**p);
     cout<<*pt<<" "<<**p<<" "<<x<<" "<<y;
     getch();
     return(0);
}