Порядок оценки оператора подписки - PullRequest
5 голосов
/ 26 сентября 2011

Существует ли какой-либо порядок вычисления выражений в случае массива.Если выражение E имеет форму E1 [E2], где E1 и E2 также являются выражениями, фиксированный порядок вычисления E1 & E2?

Вот мой код:

#include<stdio.h>
int main(){

    int a[5] = {1,2,3,4,5}; 
    (a + printf("1"))[printf("2")];
    (printf("3"))[a + printf("4")];

    return 0;
}   

Выводится как: 1243

Я скомпилировал его с помощью gcc.

Спасибо.

Ответы [ 4 ]

7 голосов
/ 26 сентября 2011

E1[E2] эквивалентно *(E1 + E2).

И в стандарте говорится, что «порядок оценки подвыражений и порядок возникновения побочных эффектов не определены». Таким образом, порядок оценки E1[E2] не является фиксированным.

3 голосов
/ 26 сентября 2011

N1256 :

6.5 Выражения
...
3 Группировка операторов и операндов указывается синтаксисом. 74) За исключением случаев, указанных далее (для вызовов функций (), &&, ||, ?: и операторов запятой), порядок вычисления подвыражений и порядок, в котором принимаются побочные эффектыместо не указано.

Таким образом, короткий ответ - «нет»;для выражения типа E1[E2] порядок вычисления подвыражений E1 и E2 не является фиксированным.

2 голосов
/ 26 сентября 2011

Порядок оценки по оператору индекса: undefined .Давайте приведем еще один пример, который не так запутан.

Проблема: рассмотрим следующее выражение:

f() + g() * h()

Приоритет совершенно ясен;умножение выигрывает у сложения, как показывает соответствующее дерево разбора:

       +
    /     \
   /       \
  f()       *
  /          \
  /           \
 g()           h()

таблица приоритетов говорит нам только о том, как сгруппированы термины, а не порядок их оценки.Единственный способ сделать порядок предсказуемым - это ввести то, что Стандарт C называет точками последовательности .Например, шаги:

x = g();
x = x * h();
x = x + f();

имеют тот же приоритет, что и раньше, но с функциями, вызываемыми в гарантированном порядке g(), h() и f().

Итак, в вашем примере вы должны ввести точки последовательности, чтобы гарантировать, что ваши операторы printf выполняются в нужном порядке.

2 голосов
/ 26 сентября 2011

Я надеюсь, что вы спрашиваете это только из любопытства, и не зависит от этого поведения для чего-то;

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

int * the_array = E1;
the_array[E2];

//or

int the_index = E2;
E1[the_index];

//is much clearer
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...