C ++的意外输出

msc*_*msc 5 c++ pointers undefined-behavior post-increment

我发现以下程序的意外输出。

这里的指针ptr指向变量的地址ii保存值10。这意味着价值ptr10。下ptr一次递增一次。这意味着现在它拥有价值11。但是在以下程序中ptr打印12

#include <iostream>
using namespace std;    

int main()
{
    int i = 10;
    int *ptr = &i;
    int j = 2;
    j += *ptr++;

    cout<<"i : "<<i<<"\n";
    cout<<"j : "<<j<<"\n";
    cout<<"ptr : "<<*ptr<<"\n";
}
Run Code Online (Sandbox Code Playgroud)

输出

i : 10
j : 12
ptr : 12
Run Code Online (Sandbox Code Playgroud)

所以我不明白为什么要ptr打印12而不是11

Vla*_*cow 15

该程序具有未定义的行为。

这个说法

j += *ptr++;
Run Code Online (Sandbox Code Playgroud)

相当于

j += *( ptr++ );
Run Code Online (Sandbox Code Playgroud)

因此,指针现在指向变量i之后,即它未指向有效对象。

因此,这句话

cout<<"ptr : "<<*ptr<<"\n";
Run Code Online (Sandbox Code Playgroud)

调用未定义的行为。

发生这种情况的方式是编译器将变量j放置在变量i之后。但是,C ++标准未指定变量的顺序。

例如,gcc编译器的输出与您显示的相同。

i : 10
j : 12
ptr : 12
Run Code Online (Sandbox Code Playgroud)

当clang编译器的输出是

i : 10
j : 12
ptr : 4201824
Run Code Online (Sandbox Code Playgroud)

你的意思是以下

j += ( *ptr )++;
Run Code Online (Sandbox Code Playgroud)

在这种情况下,输出将是

i : 11
j : 12
ptr : 11
Run Code Online (Sandbox Code Playgroud)

注意那的输出值i11因为变量i在下面的句子输出时的副作用已经应用到变量。

  • 对因果读者的说明(弗拉德已经意识到了这一点):_“因此,指针现在指向变量i之后,即它未指向有效对象。” _可以将指针指向变量之后,但取消引用该指针是不可行的(未定义的行为)。因此,类似“ std :: all_of(ptr,ptr + 1,somepredicate)`”的东西在指向非数组单个对象的指针上是可以的。 (2认同)