EgoRusMarch
@EgoRusMarch
C++ Developer

Почему это моветон?

Это из K&R:
a[i] = i++; // Значение i при присваивании неопределено

Я не могу понять почему.

Возникла мысль, что для Си любая операция -- это по сути вызов функции.

То есть, например, тут не определено какая вызовется первой, но это и не важно.
x = func_1() + func_2();

Я подумал, что и тут не определено, что первым случится: инкремент или вычисление адреса.
Но постфиксная нотация это определяет. Она должна скопировать в переменную значение и сделать над ней инкремент, а после всех операций заменить её.

Почему тогда не определено значение i при присваивании?
  • Вопрос задан
  • 727 просмотров
Решения вопроса 2
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Алексей: Евгений Шатунов:
Люди умеющие гуглить, но не понимающие, о чём речь, дают ответы! Каждый день на тостере!
Они могут нагуглить статью, в которой говорится примерно о том же, о чём задан вопрос, но, увы, не вполне.
И ни в статье, ни в ответах так и не появляется правильного ответа.
А правильный ответ -- во второй, неочевидной части пункта стандарта, описывающего выражения (C89: 3.3:2, C99: 6.5:2):

Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression. Furthermore, the prior value
shall be read only to determine the value to be stored.


Т.е. если объект модифицируется, то читать его можно с единственной целью -- для вычисления значения, которое будет в него записано. Код a[i] = i++; читает значение изменяемой переменной i с другой целью: доступ к элементу массива по индексу, результат которого не влияет на конечное значение i -- и этого достаточно, чтобы такой код попадал в категорию UB.
Ответ написан
alsopub
@alsopub
"Точка следования" - alenacpp.blogspot.ru/2005/11/sequence-points.html
Там есть почти ваш случай - x[i] = ++i;
Значение не то чтобы не определено, компилятор в праве решить что сделать сначала - вычислить адрес x[i] или сделать ++i.
Я так понял.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
То есть, например, тут не определено какая вызовется первой, но это и не важно.
x = func_1() + func_2();


Тут вы глубоко заблуждаетесь.

#include <iostream>

int x = 2;

int func_1() {
    x *= 10;
    return x;
}

int func_2() {
    x += 10;
    return x;
}

int main() {
    std::cout << func_1() + func_2() << std::endl;
    return 0;
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы