неожиданный вывод C ++ - PullRequest
       22

неожиданный вывод C ++

5 голосов
/ 25 октября 2019

Я обнаружил неожиданный вывод следующей программы.

Здесь указатель ptr указывает на адрес переменной i, а i содержит значение 10. Это означает, что значение ptr также 10. Далее 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";
}

Вывод :

i : 10
j : 12
ptr : 12

Так что я не понимаю, почему ptr печатает 12 вместо 11?

1 Ответ

15 голосов
/ 25 октября 2019

Программа имеет неопределенное поведение.

Этот оператор

j += *ptr++;

эквивалентен

j += *( ptr++ );

Таким образом, указатель теперь указывает на переменную i, которая являетсяон не указывает на действительный объект.

Таким образом, этот оператор

cout<<"ptr : "<<*ptr<<"\n";

вызывает неопределенное поведение.

Так получилось, что компилятор поместил переменную j послепеременная я. Однако порядок переменных не указан стандартом C ++.

Например, вывод компилятора gcc такой же, как вы показали.

i : 10
j : 12
ptr : 12

Хотя вывод компилятора clang равен

i : 10
j : 12
ptr : 4201824

Вы имеете в виду следующее

j += ( *ptr )++;

В этом случае вывод будет

i : 11
j : 12
ptr : 11

Обратите внимание, что выводимое значение i равно 11, поскольку переменная i выводится в следующем предложении, когда к переменной уже применен побочный эффект.

...