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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Узкое ли это место в программе? особенности компиляции или всегда верно 
V
    Опции темы
null56
Дата 2.4.2009, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Собственно вопрос относится скорее к особенностям компиляции... собственно код
Код

MyClass * p_my_class = 0;
if (p_my_class && p_my_class->myMethod())
....

Всегда интеросовал этот момент, но всегда старался его избегать
Вопрос: всегда ли данный код будет отрабатывать как надо и не вылетит мне с segmentationОМ? То есть всегда ли компилятор отработает условие слева раньше правого или все - таки это зависит от конкретного  компилятора?
Или стоит всегда использовать верный способ
Код

if (p_my_class)
{
    if (p_my_class->myMethod())
    ....
}

Надеюсь не сочтете мой вопрос слишком глупым, но мне интересно....
Заранее благодарен за помощь
PM MAIL   Вверх
GoldFinch
Дата 2.4.2009, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



if (p_my_class && p_my_class->myMethod())

эквивалентно

if (p_my_class)
{
    T r=p_my_class->myMethod();
    if ®



PM MAIL ICQ   Вверх
null56
Дата 2.4.2009, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



GoldFinch, гарантировано на любом компиляторе?
PM MAIL   Вверх
zim22
Дата 2.4.2009, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


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

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



Цитата(null56 @  2.4.2009,  14:43 Найти цитируемый пост)
всегда ли компилятор отработает условие слева раньше правого

всегда. это т.н. вычисления по ускоренной схеме. Т.е. нет смысла проверять правый операнд, если левый будет равен 0.
аналогично для операции ||
только обратитите внимание, что ускоренный вычисления работают только тогда, когда вы не переопределяете их явно.
т.е. если вы в классе напишете  operator&&(...) то это значит, что теперь забота о порядке вычислений лежит на вас.


--------------------
PM MAIL   Вверх
null56
Дата 2.4.2009, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



zim22, ну вопрос в том, чтобы компилятор не проверил правое условие и если оно верное начал проверять левое... потому что после проверки второго вперед первого, вылетит ошибка сегментации....
Вот я и спрашиваю, любой компилятор будет проверять условия слева направо, а не наоборот??? а не то, отработает ли второе, если первое ложно
PM MAIL   Вверх
Fazil6
Дата 2.4.2009, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(null56 @  2.4.2009,  14:59 Найти цитируемый пост)
GoldFinch, гарантировано на любом компиляторе? 

да гарантировано. Из-за этой гарантии нерекомендуется перегружать операторы && и ||

Добавлено через 4 минуты и 17 секунд
Цитата(null56 @  2.4.2009,  15:19 Найти цитируемый пост)
zim22, ну вопрос в том, чтобы компилятор не проверил правое условие и если оно верное начал проверять левое... потому что после проверки второго вперед первого, вылетит ошибка сегментации....
Вот я и спрашиваю, любой компилятор будет проверять условия слева направо, а не наоборот??? а не то, отработает ли второе, если первое ложно 

операторы && и || гарантируют порядок вычисления операндов стандартом. Это и является залогом того что второй операнд в зависимости от первого может не вычисляться. 
т.е. второй никогда не будет вычислен перед первым если ты не будешь  переопределять эти операторы

PM MAIL   Вверх
mes
Дата 2.4.2009, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(Fazil6 @  2.4.2009,  14:21 Найти цитируемый пост)
да гарантировано. Из-за этой гарантии нерекомендуется перегружать операторы && и || 

вот вот. гарантировано, но только для не перегруженных операторов )



--------------------
PM MAIL WWW   Вверх
zim22
Дата 2.4.2009, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


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

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



null56, из умной книжки:
Логические операторы AND и OR всегда обрабатывают свой левый операнд раньше правого. Правый операнд обрабатывается только тогда, когда левый операнд не определил результат однозначно. Такой способ обработки значений называют вычислением по сокращенной схеме (short-circuit evaluation)


--------------------
PM MAIL   Вверх
null56
Дата 2.4.2009, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Fazil6,  спасибо, теперь понятно... то есть это на уровне стандарта получается...
Спасибо всем....

Добавлено @ 15:29
zim22, спасибо так понятнее

Это сообщение отредактировал(а) null56 - 2.4.2009, 15:29
PM MAIL   Вверх
inside_pointer
Дата 3.4.2009, 00:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



null56, в арифметических операциях порядок не определён (a + b - неизвестно что сначала будет вычислено a или b), в вызове функции порядок вычисления аргументов (f(a, b, c) - a b или с, или c b или a, и может даже b a c), а логические && || и запятая (которая в роли операции, то есть f(a, (b , c), d) аргументы будут вычислятся в любом порядке, а второй аргумент (b, c) только слева направо)

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


любитель
****


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

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



Цитата(inside_pointer @  2.4.2009,  23:04 Найти цитируемый пост)
в арифметических операциях порядок не определён

не надо смешивать в одну кучу порядок_выполнения, точки_следования и "сокращенные_вычисления" smile


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


Опытный
**


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

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



&& , и + - это операции
, - может не быть операцией
порядок вычисления в операциях определён чётко, а то, что к ним не относится, может варьироваться

Код

if (p_my_class && p_my_class->myMethod())

здесь () -> имеют приоритет выше, чем у &&, постфиксные выражения выполняются слева направо поэтому будет -> потом ()

и вопрос видимо в том, может ли быть компилятор, который среагирует на приоритет

значит в стандарте должно быть где-то записано, что выражения с && || всегда выполняются слева направо, независимо от содержимого их операндов

Это сообщение отредактировал(а) inside_pointer - 3.4.2009, 02:35
PM MAIL   Вверх
mes
Дата 3.4.2009, 02:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(inside_pointer @  3.4.2009,  01:33 Найти цитируемый пост)
&& , и + - это операции

точнее сказать операторы, а вот результат их применения называется операцией

Цитата(inside_pointer @  3.4.2009,  01:33 Найти цитируемый пост)
порядок вычисления в операциях определён чётко, а то, что к ним не относится, может варьироваться

не до конца понял мысль...


Цитата(inside_pointer @  3.4.2009,  01:33 Найти цитируемый пост)
значит в стандарте должно быть где-то записано, что выражения с && || всегда выполняются слева направо, независимо от содержимого их операндов


Цитата

  5.14  Logical AND operator                              [expr.log.and]

1         logical-and-expression:
                  inclusive-or-expression
                  logical-and-expression && inclusive-or-expression
  The  &&  operator groups left-to-right.  The operands are both implic-
  itly converted to type bool (_conv_).  The  result  is  true  if  both
  operands  are true and false otherwise.  Unlike &, && guarantees left-
  to-right evaluation: the second operand is not evaluated if the  first
  operand is false.

2 The result is a bool.  All side effects of the first expression except
  for destruction of temporaries (_class.temporary_) happen  before  the
  second expression is evaluated.




--------------------
PM MAIL WWW   Вверх
inside_pointer
Дата 3.4.2009, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mes)

не до конца понял мысль...

ну, аргументы в вызове идут через запятую, она не является операцией и её свойства зависят от свойств вызова функции, а когда она в списке объявления типа int i, a, b, c;, то её свойства зависят от свойств объявления, а когда она операция, тогда она работает везде одинаково и однозначно

Код

5.14  Logical AND operator                              [expr.log.and]

чтобы это всё срабатывало так, как срабатывает, необходимо, чтобы приоритет операции && был выше, чем приоритет -> и (), иначе должна быть запись о том, почему она, находясь ниже по приоритету, выполняется первее, чем операции находящиеся выше

Код

    if (p_my_class && p_my_class->myMethod())

почему операция -> не выполнится первее && ?
PM MAIL   Вверх
mes
Дата 3.4.2009, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(inside_pointer @  3.4.2009,  16:15 Найти цитируемый пост)
чтобы это всё срабатывало так, как срабатывает, необходимо, чтобы приоритет операции && был выше, чем приоритет -> и (), иначе должна быть запись о том, почему она, находясь ниже по приоритету, выполняется первее, чем операции находящиеся выше

Вы путаете для чего нужен приоретет операций... Его действие сказывается только на зависимых операциях.


Цитата(inside_pointer @  3.4.2009,  16:15 Найти цитируемый пост)
почему операция -> не выполнится первее && ? 

почему "не" ?  
операция -> выполнится вперед операции &&, но до нее дойдет только в случае, если p_my_class "правдив."

Это сообщение отредактировал(а) mes - 3.4.2009, 17:53


--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.1033 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


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

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