| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > преобразование указателей |
| Автор: wladF 22.5.2013, 18:48 |
| Привет. Прочитал множество тем и обсуждений проблемы алиасинга памяти(указателей). Но так и никакого вывода в итоге и не сделал. Есть несколько конкретных вопросов. 1) Безопасно ли всё-таки использовать в C и C++ различные типы указателей(кроме char*), указывающих на один и тот же объект, если гарантируется, что проблем с выравниванием не будет? 2) Безопасно ли использовать в C и C++ "неактивные" члены union(после изменения другого члена)? 3) Strict aliasing rule(или другое подобное название) введена как фича GCC или это требование стандарта C и C++? 4) Если хотя бы одно из этих правил нарушено, то как вообще работают миллионы строк кода с этими "дефектами"? |
| Автор: baldina 22.5.2013, 20:28 |
| 1. указатели могут быть любые, проблема не в указателях а в разыменовании. при разыменовании все зависит от того, что конкретно находится по адресу. 2. что значит "использовать"? если это принципиально разные типы, чтение бессмысленно, но запись безопасна. если union сделан для удобства манипулирования низкоуровневыми структурами (для этого его вобщем-то и ввели), то "использование" и является целью применения union. 3. C99. в С++ нет, но компиляторы поддерживают 4. Бог милостив http://habrahabr.ru/post/114117/ |
| Автор: mabrarov 22.5.2013, 21:17 | ||||||||||
Насколько я знаю, это UB. Т.е. записать в один нестатичный член union, и прочитать то, что записали, через другой нестатичный член - это UB (за исключением тех случаев, что перечислены в цитате стандарта ниже).
Среди первых результатов поиска, что выдает Google: http://stackoverflow.com/questions/2771023/c99-strict-aliasing-rules-in-c-gcc. Т.е. strict aliasing есть уже в C++98 (параграф 3.10, пункт 15). В C++11 (взял из draft, параграф 3.10, пункт 10):
Например, в Visual C++ strict aliasing, как мне показалось за все время его использования, вообще не работает (похоже его там попросту нет). В остальных случаях:
https://blog.qt.digia.com/blog/2011/06/10/type-punning-and-strict-aliasing/, например, в Qt была проблема со strict aliasing. |
| Автор: mabrarov 23.5.2013, 02:10 | ||||
В целом согласен (хотя необязательность соблюдения strict aliasing rules компилятором не является достаточным условием, чтобы не учитывать это правило в исходном коде на C++), но (!) strict aliasing очень важное условие для "качественной" компиляции в плане использования регистровой памяти (которой становится все больше с каждым новым поколением процессоров/архитектур). Берем Google: http://www.google.com/search?hl=ru&q=Why+fortran+is+faster+than+C%2B%2B и http://stackoverflow.com/questions/146159/is-fortran-faster-than-c (ну или http://stackoverflow.com/questions/610396/languages-faster-than-c):
|
| Автор: Dem_max 23.5.2013, 09:21 | ||
Fortran был всегда быстрее, я не говорю уж о С++, а если сравнивать с Си. Даже на простом коде но его выполнит быстрее. |
| Автор: wladF 23.5.2013, 10:45 | ||||
1. Уточню. Речь шла конечно же о разыменовании таких указателей на POD-типы. 2. Чтение не бессмысленно. Пример:
По ссылке читал давно. Выводов вообще не понял. |
| Автор: mabrarov 23.5.2013, 12:38 | ||||||||
Разве это что-то меняет (за исключением особых случаев с char/unsinged char)?
Насколько я понял, http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html:
А вот "Casting through a union (2)" в "Understanding Strict Aliasing" стандартом не запрещен (т.е. разрешен), но вызывает ложные предупреждения со стороны GCC. |