Когда я сегодня читаю C Standard, это говорит о побочных эффектах
Доступ к энергозависимому объекту, изменение объекта, изменение файла или вызов функции
что любая из этих операций все побочные эффекты
и стандарт C ++ говорит
Доступ к объекту, обозначенному volatile glvalue (3.10), изменение объекта, вызов функции библиотечного ввода-вывода или вызов функции, выполняющей любую из этих операций, являются побочными эффектами.
Следовательно, поскольку оба запрещают возникновение непоследовательных побочных эффектов на одном и том же скалярном объекте, C допускает следующее, но C ++ делает его неопределенным поведением.
int a = 0;
volatile int *pa = &a;
int b = *pa + *pa;
Я правильно читаю спецификации? И в чем причина расхождения, если так?
Я не верю, что в этом отношении существует эффективная разница между C и C ++. Хотя формулировка секвенирования варьируется, конечный результат один и тот же: оба результата приводят к неопределенному поведению (хотя C, кажется, указывает, что оценка будет успешной, но с неопределенным результатом).
В C99 (извините, C11 под рукой нет), параграф 5.1.2.3.5 определяет:
— В точках последовательности изменчивые объекты стабильны в том смысле, что предыдущие обращения
полный и последующий доступ еще не произошел.
В сочетании с вашей цитатой из 5.1.2.3.2 будет указывать значение pa
не будет в стабильном состоянии, по крайней мере, один из доступов к pa
, Это логично, поскольку компилятору будет разрешено оценивать их в любом порядке, только один раз или одновременно (если это возможно). Это на самом деле не определяет, что стабильный значит однако.
В C ++ 11 есть явная ссылка на непоследовательные операции в 1.9.13. Тогда точка 15 указывает, что такие непоследовательные операции над одним и тем же операндом не определены. поскольку неопределенное поведение может означать, что что-нибудь случится, возможно, сильнее, чем С неустойчивый поведение. Однако в обоих случаях нет гарантированного результата вашего выражения.
Других решений пока нет …