Выражение x [- i] = y [++ i] = z [i ++], которое вычисляется первым? - PullRequest
1 голос
/ 02 февраля 2011

Когда оценка l-значения предшествует , оценка r-значения и присвоения также возвращает значение, какое из следующего оценивается первым?

int i = 2;
int x[] = {1, 2, 3};
int y[] = {4, 5, 6};
int z[] = {7, 8, 9};

x[--i] = y[++i] = z[i++]; // Out of bound exception or not?

ПРИМЕЧАНИЕ : общий C-подобный язык с вычислением l-значения первым. Из моего учебника :

В некоторых языках, например C, назначение считается оператор, чья оценка, кроме того для получения побочного эффекта, а также возвращает вычисленное таким образом значение r Таким образом, если мы напишем в C:

x = 2;

оценка такой команды, в дополнение к присвоению значения 2 х, возвращает значение 2. Следовательно, в C, мы также можем написать:

y = x = 2;

, что следует интерпретировать как:

(y = (x = 2));

Ответы [ 3 ]

6 голосов
/ 02 февраля 2011

Я совершенно уверен, что поведение в этом случае не определено, потому что вы изменяете и читаете значение переменной i несколько раз между последовательными точками последовательности.

Кроме того, в C, массивыобъявляются путем размещения [] после имени переменной, а не после типа:

int x[] = {1, 2, 3};

Edit:

Удалите массивы из вашего примера, потому что они [по большей части [] не имеет значения.Теперь рассмотрим следующий код:

int main(void)
{
    int i = 2;
    int x = --i + ++i + i++;
    return x;
}

Этот код демонстрирует операции, выполняемые с переменной i в исходном коде, но без массивов.Вы можете видеть более четко, что переменная i изменяется в этом выражении более одного раза.Когда вы полагаетесь на состояние переменной, которая изменяется между последовательными точками последовательности, поведение не определено.Разные компиляторы будут (и будут делать, GCC возвращает 6, Clang возвращает 5) даст разные результаты, и один и тот же компилятор может дать разные результаты с разными вариантами оптимизации или без всякой видимой причины.не определено поведение, потому что i изменяется несколько раз между последовательными точками последовательности, то же самое можно сказать и о вашем исходном коде.Оператор присваивания не вводит новую точку последовательности.

2 голосов
/ 02 февраля 2011

Общее

В C порядок любой операции между двумя точками последовательности не должен зависеть от.Я не помню точную формулировку из стандарта, но именно по этой причине

i = i++;

является неопределенным поведением.Стандарт определяет список вещей, составляющий sequence points, из памяти это

  1. точка с запятой после оператора
  2. оператор запятой
  3. оценка всехАргументы функции перед вызовом функции
  4. && и ||операнд

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

Конкретный

Независимо от того, насколько четко определен порядок оценки и присвоенияпеременные x, y и z, для

x[--i] = y[++i] = z[i++];

это утверждение не может быть ничем иным, как неопределенным поведением из-за i--, i++ и i++.С другой стороны,

x[i] = y[i] = z[i];

четко определено, но я не уверен, какой статус для порядка оценки для этого.Однако, если это важно, я бы предпочел, чтобы это было разделено на два утверждения вместе с комментарием «Важно, чтобы ... был назначен / инициализирован до ... потому что ...».

0 голосов
/ 02 февраля 2011

я думаю, что это то же самое, что и

x[3] = y[4] = z[2];
i = 3;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...