Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> преобразование указателей 
:(
    Опции темы
wladF
Дата 22.5.2013, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 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
PM MAIL   Вверх
baldina
Дата 22.5.2013, 20:28 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



1. указатели могут быть любые, проблема не в указателях а в разыменовании. при разыменовании все зависит от того, что конкретно находится по адресу.
2. что значит "использовать"? если это принципиально разные типы, чтение бессмысленно, но запись безопасна. если union сделан для удобства манипулирования низкоуровневыми структурами (для этого его вобщем-то и ввели), то "использование" и является целью применения union.
3. C99. в С++ нет, но компиляторы поддерживают
4. Бог милостив

подробно
PM MAIL   Вверх
mabrarov
Дата 22.5.2013, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: 8
Всего: 9



Цитата(wladF @ 22.5.2013,  18:48)
2) Безопасно ли использовать в C и C++ "неактивные" члены union(после изменения другого члена)?

Насколько я знаю, это UB. Т.е. записать в один нестатичный член union, и прочитать то, что записали, через другой нестатичный член - это UB (за исключением тех случаев, что перечислены в цитате стандарта ниже).

Цитата(wladF @ 22.5.2013,  18:48)
3) Strict aliasing rule(или другое подобное название) введена как фича GCC или это требование стандарта C и C++?

Среди первых результатов поиска, что выдает Google: http://stackoverflow.com/questions/2771023...-rules-in-c-gcc.
Т.е. strict aliasing есть уже в C++98 (параграф 3.10, пункт 15).
В C++11 (взял из draft, параграф 3.10, пункт 10):
Цитата
If a program attempts to access the stored value of an object through a glvalue of other than one of the
following types the behavior is undefined:
— the dynamic type of the object,
— a cv-qualified version of the dynamic type of the object,
— a type similar (as defined in 4.4) to the dynamic type of the object,
— a type that is the signed or unsigned type corresponding to the dynamic type of the object,
— a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type
of the object,
— an aggregate or union type that includes one of the aforementioned types among its elements or nonstatic
data members (including, recursively, an element or non-static data member of a subaggregate
or contained union),
— a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,
— a char or unsigned char type.

Цитата(wladF @ 22.5.2013,  18:48)
4) Если хотя бы одно из этих правил нарушено, то как вообще работают миллионы строк кода с этими "дефектами"?

Например, в Visual C++ strict aliasing, как мне показалось за все время его использования, вообще не работает (похоже его там попросту нет). 
В остальных случаях: 
Цитата(baldina)
Бог милостив

Вот, например, в Qt была проблема со strict aliasing.

Это сообщение отредактировал(а) mabrarov - 22.5.2013, 21:19
PM MAIL WWW Skype   Вверх
volatile
Дата 23.5.2013, 00:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(mabrarov @  22.5.2013,  21:17 Найти цитируемый пост)
в Visual C++ strict aliasing, как мне показалось за все время его использования, вообще не работает 

strict aliasing -это всего лишь оптимизация. 
Точнее некоторое послабление компилятору, в надежде что он сгенерит более оптимальный код,
и как любое послабление - потенциальный источник багов.

PM MAIL   Вверх
mabrarov
Дата 23.5.2013, 02:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: 8
Всего: 9



Цитата(volatile @ 23.5.2013,  00:47)
strict aliasing -это всего лишь оптимизация. 
Точнее некоторое послабление компилятору, в надежде что он сгенерит более оптимальный код,
и как любое послабление - потенциальный источник багов.

В целом согласен (хотя необязательность соблюдения strict aliasing rules компилятором не является достаточным условием, чтобы не учитывать это правило в исходном коде на C++), но (!) strict aliasing очень важное условие для "качественной" компиляции в плане использования регистровой памяти (которой становится все больше с каждым новым поколением процессоров/архитектур).
Берем Google: Why fortran is faster than C++ и находим (ну или вот это):
Цитата
The languages have similar feature-set. The performance difference comes from the fact that fortran says aliasing is not allowed. Any code that has aliasing is not valid fortran but it is up to the programmer and not the compiler to detect these errors. Thus fortran compilers ignore possible aliasing of memory pointers and allows them to generate more efficient code.


Это сообщение отредактировал(а) mabrarov - 23.5.2013, 02:18
PM MAIL WWW Skype   Вверх
Dem_max
Дата 23.5.2013, 09:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 4
Всего: 39



Цитата

Берем Google: Why fortran is faster than C++ и находим (ну или вот это):

Fortran был всегда быстрее, я не говорю уж о С++, а если сравнивать с Си. Даже на простом коде но его выполнит быстрее.


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
wladF
Дата 23.5.2013, 10:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 2.6.2009

Репутация: нет
Всего: нет



Цитата(baldina @ 22.5.2013,  20:28)
1. указатели могут быть любые, проблема не в указателях а в разыменовании. при разыменовании все зависит от того, что конкретно находится по адресу.
2. что значит "использовать"? если это принципиально разные типы, чтение бессмысленно, но запись безопасна. если union сделан для удобства манипулирования низкоуровневыми структурами (для этого его вобщем-то и ввели), то "использование" и является целью применения union.
3. C99. в С++ нет, но компиляторы поддерживают
4. Бог милостив

подробно

1. Уточню. Речь шла конечно же о разыменовании таких указателей на POD-типы. 

2. Чтение не бессмысленно. Пример:
Код

Union U {
    int a;
    float b;
} u;
..
u.a = //.. используем целочисленные операции 
return u.b;


По ссылке читал давно. Выводов вообще не понял.
PM MAIL   Вверх
mabrarov
Дата 23.5.2013, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: 8
Всего: 9



Цитата(wladF @ 23.5.2013,  10:45)
1. Уточню. Речь шла конечно же о разыменовании таких указателей на POD-типы. 

Разве это что-то меняет (за исключением особых случаев с char/unsinged char)? 

Цитата(wladF @ 23.5.2013,  10:45)
2. Чтение не бессмысленно. Пример:
Код

Union U {
    int a;
    float b;
} u;
..
u.a = //.. используем целочисленные операции 
return u.b;

Насколько я понял, это UB, если следовать стандарту, но на на практике настолько часто применяемый прием, что компиляторы "прощают" такие ошибки:
Цитата
Casting through a union (1)
...
Strictly speaking, reading a member of a union different from the one written to is undefined in ANSI/ISO C99 except in the special case of type-punning to a char*, similar to the example below: Casting to char*. However, it is an extremely common idiom and is well-supported by all major compilers. As a practical matter, reading and writing to any member of a union, in any order, is acceptable practice.

А вот "Casting through a union (2)" в "Understanding Strict Aliasing" стандартом не запрещен (т.е. разрешен), но вызывает ложные предупреждения со стороны GCC.
PM MAIL WWW Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1215 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.