Скопируйте скобки в порядок и определите выражение undefined?

Я просто шел, хотя мой учебник, когда я столкнулся с этим вопросом

  • Каким будет значение a после следующего выражения?
    Предположим, что начальное значение a = 5. Укажите шаги
    • а + = (A ++) + (++ а)

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

Итак, мой вопрос:

  • Определяет ли применение круглых скобок поведение undefined?
  • Является точкой последовательности, созданной после оценки выражения в скобках?
  • Если это определено, как скобки имеют значение, так как ++ и() имеют одинаковый приоритет

Примечание: хорошо объясненный и ясный ответ получит мой голос

Ответ 1

Нет, применение круглых скобок не приводит к определенному поведению. Он по-прежнему undefined. В стандарте C99 и разделе 6.5 и пункте 2 говорится:

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

Включение подвыражения в круглые скобки может привести к порядку оценки подвыражений, но не создает точку последовательности. Поэтому он не гарантирует, когда будут иметь место побочные эффекты подвыражений, если они производят их. Повторное цитирование стандарта C99 и раздел 5.1.2.3 и para; 2

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

Для полноты, следующие точки последовательности, установленные стандартом C99 в Приложении C.

  • Вызов функции после оценки аргументов.

  • Конец первого операнда следующих операторов: логический И &&; логическое ИЛИ ||; условный ?; запятая ,.

  • Конец полного объявления.

  • Конец полного выражения; выражение в выражении выражения; управляющее выражение оператора выбора (, еслиили ); управляющее выражение while или doвыражение; каждое из выражений оператора для; выражение в выражении return.

  • Непосредственно перед возвратом функции библиотеки.

  • После действий, связанных с каждым форматированным спецификатором преобразования функции ввода/вывода.

  • Непосредственно до и сразу после каждого вызова функции сравнения, а также между любым вызовом функции сравнения и любым перемещение объектов, переданных в качестве аргументов для этого вызова.

Ответ 2

Добавление скобок не создает точку последовательности, а в более современных стандартах она не создает секвенированных до отношений по отношению к побочным эффектам, что является проблемой с выражением, которое у вас есть, если не отмечено, остальное это будет с уважением на С++ 11. Первичное выражение - это первичное выражение, охватываемое в разделе 5.1 Первичные выражения, которые имеют следующую грамматику (акцент мой вперед):

primary-expression:
  literal
  this
  ( expression )
  [...]

и в пункте 6 говорится:

Выражение в скобках - это основное выражение, тип и значение которого идентичны типу заключенного выражения. Наличие скобок не влияет на то, является ли выражение lvalue. Выражение в скобках можно использовать в тех же контекстах, что и те, в которых может использоваться замкнутое выражение, и с тем же значением, если не указано иное.

postfix ++ является проблематичным, поскольку мы не можем определить, когда будет происходить побочный эффект обновления a pre С++ 11, а в C это относится как к операциям postfix ++, так и к prefix ++. Относительно того, как поведение undefined изменилось для prefix ++ в С++ 11, см. Секвенирование оператора Assignment в выражениях C11.

Операция += проблематична, поскольку:

[...] E1 op = E2 эквивалентен E1 = E1 op E2, за исключением того, что E1 является оценивается только один раз [...]

Итак, в С++ 11 следующее из undefined в определение:

a = ++a + 1 ;

но это остается undefined:

a = a++ + 1 ;

и оба из них - undefined pre С++ 11 и как на C99, так и на C11.

Из стандартного раздела проекта С++ 11 1.9 В пункте 15 выполнения программы говорится:

За исключением тех случаев, когда отмечено, оценки операндов отдельных операторов и подвыражений отдельных выражений не имеют никакого значения. [Примечание. В выражении, которое оценивается более одного раза во время выполнения программы, неоперабельные и неопределенно упорядоченные оценки его подвыражений не обязательно должны выполняться последовательно в разных оценках. -end note] Вычисления значений операндов оператора секвенируются перед вычислением значения результата оператора. Если побочный эффект скалярного объекта не влияет на какой-либо другой побочный эффект на один и тот же скалярный объект или вычисление значения, используя значение одного и того же скалярного объекта, поведение undefined.