![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
wladF |
|
|||
Новичок Профиль Группа: Участник Сообщений: 7 Регистрация: 2.6.2009 Репутация: нет Всего: нет |
Привет.
Прочитал множество тем и обсуждений проблемы алиасинга памяти(указателей). Но так и никакого вывода в итоге и не сделал. Есть несколько конкретных вопросов. 1) Безопасно ли всё-таки использовать в C и C++ различные типы указателей(кроме char*), указывающих на один и тот же объект, если гарантируется, что проблем с выравниванием не будет? 2) Безопасно ли использовать в C и C++ "неактивные" члены union(после изменения другого члена)? 3) Strict aliasing rule(или другое подобное название) введена как фича GCC или это требование стандарта C и C++? 4) Если хотя бы одно из этих правил нарушено, то как вообще работают миллионы строк кода с этими "дефектами"? Это сообщение отредактировал(а) wladF - 22.5.2013, 18:54 |
|||
|
||||
baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
1. указатели могут быть любые, проблема не в указателях а в разыменовании. при разыменовании все зависит от того, что конкретно находится по адресу.
2. что значит "использовать"? если это принципиально разные типы, чтение бессмысленно, но запись безопасна. если union сделан для удобства манипулирования низкоуровневыми структурами (для этого его вобщем-то и ввели), то "использование" и является целью применения union. 3. C99. в С++ нет, но компиляторы поддерживают 4. Бог милостив подробно |
|||
|
||||
mabrarov |
|
||||||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 100 Регистрация: 12.1.2011 Где: Казань Репутация: 8 Всего: 9 |
Насколько я знаю, это UB. Т.е. записать в один нестатичный член union, и прочитать то, что записали, через другой нестатичный член - это UB (за исключением тех случаев, что перечислены в цитате стандарта ниже).
Среди первых результатов поиска, что выдает Google: http://stackoverflow.com/questions/2771023...-rules-in-c-gcc. Т.е. strict aliasing есть уже в C++98 (параграф 3.10, пункт 15). В C++11 (взял из draft, параграф 3.10, пункт 10):
Например, в Visual C++ strict aliasing, как мне показалось за все время его использования, вообще не работает (похоже его там попросту нет). В остальных случаях:
Вот, например, в Qt была проблема со strict aliasing. Это сообщение отредактировал(а) mabrarov - 22.5.2013, 21:19 |
||||||||||
|
|||||||||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 37 Всего: 85 |
strict aliasing -это всего лишь оптимизация. Точнее некоторое послабление компилятору, в надежде что он сгенерит более оптимальный код, и как любое послабление - потенциальный источник багов. |
|||
|
||||
mabrarov |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 100 Регистрация: 12.1.2011 Где: Казань Репутация: 8 Всего: 9 |
В целом согласен (хотя необязательность соблюдения strict aliasing rules компилятором не является достаточным условием, чтобы не учитывать это правило в исходном коде на C++), но (!) strict aliasing очень важное условие для "качественной" компиляции в плане использования регистровой памяти (которой становится все больше с каждым новым поколением процессоров/архитектур). Берем Google: Why fortran is faster than C++ и находим (ну или вот это):
Это сообщение отредактировал(а) mabrarov - 23.5.2013, 02:18 |
||||
|
|||||
Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 4 Всего: 39 |
Fortran был всегда быстрее, я не говорю уж о С++, а если сравнивать с Си. Даже на простом коде но его выполнит быстрее. -------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
wladF |
|
||||
Новичок Профиль Группа: Участник Сообщений: 7 Регистрация: 2.6.2009 Репутация: нет Всего: нет |
1. Уточню. Речь шла конечно же о разыменовании таких указателей на POD-типы. 2. Чтение не бессмысленно. Пример:
По ссылке читал давно. Выводов вообще не понял. |
||||
|
|||||
mabrarov |
|
||||||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 100 Регистрация: 12.1.2011 Где: Казань Репутация: 8 Всего: 9 |
Разве это что-то меняет (за исключением особых случаев с char/unsinged char)?
Насколько я понял, это UB, если следовать стандарту, но на на практике настолько часто применяемый прием, что компиляторы "прощают" такие ошибки:
А вот "Casting through a union (2)" в "Understanding Strict Aliasing" стандартом не запрещен (т.е. разрешен), но вызывает ложные предупреждения со стороны GCC. |
||||||||
|
|||||||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |