Qraizer
Advanced Member | Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору Стандарт просто не запрещает реализациям выполнять агрессивную оптимизацию подвыражений. Вот и всё. Именно поэтому в нём и записано, что порядок вычислений операндов для операций - а также аргументов, передаваемых в функцию - неопределён, если только они не разделяются точками следования, каковые вносятся ; и упомянутыми мною выше исключениями. Точка следования обязывает компиляторы привести значения всех переменных в соответствие с ожидаемым программистом результатом, и следовательно заканчивает область действия всех накопленных к этому времени побочных эффектов. А так как оптимизация - это сугубо внутренее и личное дело каждой реализии, поэтому даже на одном и том же компиляторе при собсем чуть-чуть разных условиях можно ожидать разных результатов. Например в *a = *a++ * b оптимизатор имеет право решить сначала вычислить a++, потом *(a++), потом (*a++ * b), потом записать результат a++ в память, потом повторно использовать *a (т.к. *a и *a++ должны были бы обращаться по одному и тому же адресу) и записать туда результат умножения. Вот и пример "неправильно" скомпилированного выражения. По этой же причине нельзя писать a^=b^=a^=b, т.к. оптимизатор может решить записать в память результаты ксоров в удобном для себя порядке. А вот так - можно: b^=a^=b, a^=b; Операция , рулит. etc
---------- Одни с годами умнеют, другие становятся старше. |
| Всего записей: 613 | Зарегистр. 08-08-2006 | Отправлено: 19:53 11-05-2007 | Исправлено: Qraizer, 20:19 11-05-2007 |
|