|
Тип данных в Кейле |
|
|
|
Jul 12 2011, 08:48
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(demiurg_spb @ Jul 12 2011, 11:02)  Все современные компиляторы самостоятельно будут использовать сдвиг вместо деления когда это оправдано Возможно, но иногда удивляешся коду, который нагенерил "современный" компилятор... Цитата(demiurg_spb @ Jul 12 2011, 11:02)  (x*5)/8 совершенно равнозначно (х*5)>>3 А, вот тут я с Вами не согласен. Насколько я помню (поправьте, если я не прав): раставленные в выражении (x*5)/8 скобочки никак не определяют последовательность выполнения операций. Поскольку приоритеты операций * и / одинаковые, то выражение (x*5)/8 с точки зрения компилятора в соответствии со стандартом эквивалентно x*5/8 или даже x*(5/8). Компилятор вправе на этапе трансляции вычислить часть выражения, если операнды - константы. Но, поскольку 5/8 равно нулю, то можно получить результат далёкий от ожидаемого... При вычислении выражения (х*5)>>3 последовательность вычислений однозначно определена приоритетами.
|
|
|
|
|
Jul 12 2011, 09:33
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Проверил живьём на максимальном уровне оптимизации выражение Код uint32_t x; x = (x*5)/8; превратилось в Код 0x08001C88 4C06 LDR r4,[pc,#24]; @0x08001CA4 0x08001C8A 6820 LDR r0,[r4,#0x00] 0x08001C8C EB000080 ADD r0,r0,r0,LSL #2 0x08001C90 08C0 LSRS r0,r0,#3 0x08001C92 6020 STR r0,[r4,#0x00] Всё как и ожидалось сначала умножил на 5 (хитро сложив и сдвинув), а потом поделил на 8 (сдвинув направо на 3). Стандарта в части скобочек не могу процитировать, но полагаю что scifi близок к истине.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Jul 12 2011, 09:43
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(scifi @ Jul 12 2011, 13:22)  нафиг скобки вообще нужны, если они ни на что не влияют? Я не утверждал, что скобки "ни на что не влияют". Например в выражении (х*5)>>3 они (скобки) очень даже "влияют". А, вот, в выражении (x*5)/8 компилятор вправе их игнорировать... Пример попроще: выражение (х+2)-1. Как Вы думаете: компилятор сгенерирует 1) выполнение двух операций или 2) преобразует в х+(2-1) и, соответственно, вычислит на этапе трансляции (2-1) и, в конце концов, получим х+1 ?
|
|
|
|
|
Jul 12 2011, 09:55
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(Палыч @ Jul 12 2011, 13:43)  А, вот, в выражении (x*5)/8 компилятор вправе их игнорировать... Ну, если мне не верите, проверьте сами. По-вашему выражение (x*5)/8 даёт результат 0 вне зависимости от значения x. Это легко проверить. Или Вы хотите сказать, что результат выражения зависит от уровня оптимизации? Тогда это вообще нонсенс. Кому нужна оптимизация, коверкающая результат простейшего арифметического выражения? Не говоря уже о том, что это просто противоречит стандарту языка Си. Добавление: Да, в стандарте языка указаны случаи, в которых порядок вычисления не определён. Например, порядок вычисления аргументов функции. Или операндов побитового И или ИЛИ (& или |). Но (x*5)/8 - не тот случай. Стандарт чётко описывает, что сначала идёт умножение, а потом - деление (кстати, и без скобок тоже, по правилам приоритетов операторов). Причём умножение и деление происходят в "абстрактной машине". Что там нагенерит компилятор - его дело, лишь бы результат был бы такой же, как в "абстрактной машине". Как мы видели, он может нагенерить сдвиги и сложения. Или вообще подставить константу, если результат выражения известен на этапе компиляции.
|
|
|
|
|
Jul 12 2011, 10:18
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(demiurg_spb @ Jul 12 2011, 15:03)  Для себя уже давно доказал. Для разных компиляторов... То есть какой-то компилятор может "наплевать" на скобки? Какой? Upd. Проверил на IAR-е. Сложения и вычитания костант, идущие друг за другом даже за скобками он упрощает. Потому как переполнения на них не влияют. А умножения и деления нет.
Сообщение отредактировал GetSmart - Jul 12 2011, 10:27
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jul 12 2011, 10:27
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(GetSmart @ Jul 12 2011, 14:18)  То есть какой-то компилятор может "наплевать" на скобки? Какой? Как я понял, demiurg_spb и не намекает на то, что компилятор может наплевать на скобки. Напротив: Цитата(demiurg_spb @ Jul 12 2011, 13:50)  Когда можно упростить выражение без изменения сути, это будет сделано компилятором несомненно. В данном случае перестановка скобок (x*5)/8 -> x*(5/8) очень даже изменяет суть, а потому компилятору не разрешена. Что мы и пытаемся объяснить Палычу. Не соглашусь только, что компилятор применит оптимизацию "несомненно", так как видел немало тупых компиляторов.
|
|
|
|
|
Jul 12 2011, 10:49
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(scifi @ Jul 12 2011, 13:55)  Ну, если мне не верите, проверьте сами. По-вашему выражение (x*5)/8 даёт результат 0 вне зависимости от значения x. Это легко проверить. Или Вы хотите сказать, что результат выражения зависит от уровня оптимизации? Нет, зависит от "уровня" трансляторописателей, вернее их понимания "духа и буквы" стандарта. Цитата(scifi @ Jul 12 2011, 13:55)  Стандарт чётко описывает, что сначала идёт умножение, а потом - деление (кстати, и без скобок тоже, по правилам приоритетов операторов). Тут с Вами не соглашусь. Приоритет всех мультипликативных операций (*, /, %) одинаков. Цитата(GetSmart @ Jul 12 2011, 14:18)  То есть какой-то компилятор может "наплевать" на скобки? В некоторых случаях - да, может "наплевать". Речь идёт о операциях с одинаковым приоритетом в скобках и за скобками. Нет времени искать точную формулировку в стандарте, но, по-памяти: "порядок выполнения операций может быть изменён, если это не приводит к изменению значения выражения". С учетом того, что при выполнении операций могут возникать всякие-разные "неприятности" (типа переполнения результата), то понятие "неизменный результат" становится очень расплывчатым, и тут - простор для трансляторописателей...
|
|
|
|
|
Jul 12 2011, 10:59
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Палыч @ Jul 12 2011, 15:49)  Нет времени искать точную формулировку в стандарте, но, по-памяти: "порядок выполнения операций может быть изменён, если это не приводит к изменению значения выражения". Было такое. Но это исключительно когда нет скобок. Не выдумывайте свою интерпретацию Цитата(Палыч @ Jul 12 2011, 15:49)  В некоторых случаях - да, может "наплевать". Речь идёт о операциях с одинаковым приоритетом в скобках и за скобками. Но нельзя распостранять эти некоторые случаи на все, в силу собственного незнания этих случаев. Именно это и есть уровень вредных советов. Лучше приводить дословную формулировку. По логике, это можно делать, когда перепонения при исполнении операций не могут повлиять на результат. То есть то же, что и в школьной математике, но с учётом ограниченности (временных) переменных. Это подходит к сложениям/вычитаниям, лог операциям, но не относится к сдвигам, умнодениям/делениям.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jul 12 2011, 11:19
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(Палыч @ Jul 12 2011, 14:49)  Нет, зависит от "уровня" трансляторописателей, вернее их понимания "духа и буквы" стандарта. То есть кто-то может неправильно понять стандарт и, соответвственно, написать компилятор с глюком. Спасибо за напоминание об это очевидном факте. Цитата(Палыч @ Jul 12 2011, 14:49)  Тут с Вами не соглашусь. Приоритет всех мультипликативных операций (*, /, %) одинаков. Я имел в виду в данном конкретном выражении: (x*5)/8. Цитата(Палыч @ Jul 12 2011, 14:49)  Нет времени искать точную формулировку в стандарте, но, по-памяти: "порядок выполнения операций может быть изменён, если это не приводит к изменению значения выражения". Нет нужды, я уже нашёл: Цитата The semantic descriptions in this International Standard describe the behavior of an abstract machine in which issues of optimization are irrelevant. ... In the abstract machine, all expressions are evaluated as specified by the semantics. An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object). Цитата(Палыч @ Jul 12 2011, 14:49)  С учетом того, что при выполнении операций могут возникать всякие-разные "неприятности" (типа переполнения результата), то понятие "неизменный результат" становится очень расплывчатым, и тут - простор для трансляторописателей... В случае с целыми беззнаковыми числами никакой расплывчатости нет: Цитата A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type. Не разобравшись в ситуации, не давайте вредных советов. Вдруг неокрепшие умы всерьёз воспримут.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|