![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
J0ker |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 4 Всего: 14 |
вот тут вы совершенно НЕ правы связано это не с возможностью/невозможностью конкретного преобразования типа, а с оптимизацией дело в том, что компилятор зачастую не в состоянии отследить алиасинг, что может приводить при оптимизации к сайдэффектам например следующий код:
без оптимизации может выдавать "10", а с оптимизацией - "5" если такое случится, и вы посмотрите на оптимизированный ассемблерный код, то сможете заметить странную вещь - printf либо вызывается с константой - совершенно не взирая на реальное значение переменной, либо присвоение происходит после вызова printf Обсуждение подобного эффекта тут: http://www.rsdn.ru/Forum/message/2630988.flat.1.aspx ЗЫЖ да, если что - вышеприведенный пример ессесна не портируем на биг-ендиан будет явная лажа ![]() Это сообщение отредактировал(а) J0ker - 18.12.2008, 18:52 |
||||
|
|||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 4 Всего: 14 |
да, вот еще
5.17/8
|
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Речь идет совсем не о том, чтобы преобразовать типы и спать спокойно, а том, чтобы сделать это ВРЕМЕННО.
Если ты собираешься запихнуть double в int64, а потом пользоваться этим int'ом, то да, это не безопасно. Но если int64 использовать как временное хранилище для битов дабла, то ничего с твоим даблом не случится. А твой пример с printf вообще из другой оперы. -------------------- ... |
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 4 Всего: 14 |
ну не знаю... надо анрила спросить... что-то мне кажется формально это подподает под UB
|
|||
|
||||
GoldFinch |
|
|||
![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2141 Регистрация: 30.11.2008 Репутация: 15 Всего: 26 |
где это уже обсуждалось, толко речь шла о float
так вот в переменную размером N байт можно запихнуть любую другую переменную N байт и ничего с ней не случиться. |
|||
|
||||
UnrealMan |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
Начнём с того, что в стандарте C++ нету встроенного типа __int64
![]() Далее, т.к. стандарт не обязывает double иметь не более строгие требования к выравниванию, чем __int64, то результат reinterpret_cast-а из __int64 * в double * - unspecified.
Отличается. На некоторых архитектурах несоблюдение выравнивания приводит к аппаратному исключению. Так что memcpy надёжнее. Это сообщение отредактировал(а) UnrealMan - 19.12.2008, 21:17 |
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 4 Всего: 14 |
UnrealMan, а конкретно под 3.10/15 и 5.17/8 это подпадает?
|
|||
|
||||
UnrealMan |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
||||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Возможно, в случае с выравниванием и да. Но если я заведу union как предлагала, с обоими этими типами - согласись, все должно быть ок. Хотя, конечно, не факт, что тогда размер юниона будет равен размеру double. Но это уже поддается контролю при сборке. Кроме того, в жизни такого не встречала (разницы в выравнивании). Конечно, на какой-то отдельно взятой и не очень распростаненной платформе - наверное, возможно. Но человек, который на ней програмирует, видимо, должен это знать. А код, который пишется под широко распросраненные платформы вряд ли кто-то расчитывает перенести на какие-то специальные, не прикладывая специальных усилий. Так что все эти рассуждения очень похожи на теоретическую опастность попасть под кирпич, прогуливаясь по улице. -------------------- ... |
|||
|
||||
UnrealMan |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
По стандарту нет (см. 3.10/15), но с практической точки зрения, скорее всего, да (если размер double не превышает 64 бит). Другое дело, что непонятно, зачем это нужно - переводить double в __int64 и обратно. |
|||
|
||||
J0ker |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 986 Регистрация: 17.9.2008 Репутация: 4 Всего: 14 |
разве это не разрешает делать это через union?:
|
|||
|
||||
UnrealMan |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
||||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Если речь о конвертации, а выравнивание неодинаковое (или что-то еще неодинаковое), то обмен через union действительно некорректен - нет гарантии, что все биты будут общими. Корректно только само присваивание. Поскольку union должен быть выделен так, чтобы все комфортно разместились. Я имела в виду именно это.
Ну, скажем, чтобы передать параметр процедуре, принимающей исключительно int64. Реальный пример (здесь правда речь идет o паре float\DWORD) - послать сообщение с параметром float (притом что там есть только DWORD параметры). -------------------- ... |
|||
|
||||
UnrealMan |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 722 Регистрация: 30.3.2006 Репутация: 27 Всего: 32 |
Ну, если процедура изначально написана через ж., и альтернативы её использованию нет, то тут всё понятно. В норме же аргументы неизвестных типов передаются через указатели void * или char *, а не запихиваются в целочисленные объекты. |
|||
|
||||
GoldFinch |
|
|||
![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2141 Регистрация: 30.11.2008 Репутация: 15 Всего: 26 |
UnrealMan, а нафига создавать переменную в которой будет храниться это значение, вычислять указатель на это значение, если можно просто передать его по значению?
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |