Подтвердить что ты не робот

Разделители запятой в определении типа в C гарантируют заказ?

Comma операторы имеют младший приоритет и ассоциативность слева направо, поэтому это гарантирует порядок:

i = ++j, j = i++;

i будет равно 2, а затем j будет 1 после этого утверждения, если i и j будут одновременно 0.

Однако, действительно ли запятые разделители в определении типа в C также гарантируют порядок? Например,

int i = 1, j = ++i;
4b9b3361

Ответ 1

Ваш пример с оператором запятой i = ++j, j = i++;, является корректным, поскольку оператор запятой является точкой последовательности.

Приоритет/ассоциативность недостаточно для того, чтобы гарантировать это - они отличаются от порядка оценки и точек последовательности. Например, i * 2 + i++ * 3 - undefined, потому что нет точек последовательности.


Разделитель запятой между деклараторами, например. int i = 1, j = i++;, также является точкой последовательности. Это охватывается C11 6.7.6/3, C99 6.7.5/3:

Полный декларатор - это декларатор, который не является частью другого декларатора. Конец полного декларатора является точкой последовательности.

Итак, после i = 1 есть точка последовательности, и этот код определен корректно.


Однако разделитель запятой между аргументами функции f(i, i++) не является точкой последовательности; так что код вызывает поведение undefined.


Примечание. В C11 термин "точка последовательности" в основном заменялся более сложными отношениями секвенирования, чтобы четко указать модель потоковой передачи, но это не влияет на описанное выше обсуждение.

Ответ 2

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

int i = 1;
int j = i++;

i уже был выделен где-то в памяти, поэтому все, что происходит с j, - это значение, которое хранится в i, увеличивает его и устанавливает его равным j.

Итак, в случае

int i = 1, j = ++i;

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

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

Ответ 3

Предполагая, что C работает так же, как С# в этом отношении, значения, разделенные запятыми (int я = 0, j = 0;), должны оставаться в порядке.

Разница в я ++ vs ++ я - время проверки:

int i = 0;

bool iGTZ = i++ > 0;//false

i = 0; iGTZ = ++i > 0;//true

Немного больше, чем вы просили, но заказ объявления гарантирован. И если вы или кто-то читающий это не знали, что, надеюсь, это помогает.:)