Модераторы: 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   Вверх
Ln78
Дата 3.4.2009, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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

inside_pointer
Это разные вещи. Если бы операция && была приоритетнее ->, то выражение, о котором был задан вопрос было бы эквивалентно:
Код

if ( ( p_my_class && p_my_class ) -> myMethod() )
 
 smile 
PM MAIL   Вверх
inside_pointer
Дата 4.4.2009, 01:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mes)

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

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

Ln78, он спросил так, как спросил - не разыменуется ли нулевой указатель smile

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


depict1
****


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

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



Цитата(inside_pointer @  4.4.2009,  01:42 Найти цитируемый пост)
почему она будет так выполняться, каким образом она проверит, что первый операнд правдив, по какому правилу ?

по такому правилу: если в результате вычисления выражения мы получим 0 - то FALSE, иначе - TRUE
http://forum.vingrad.ru/index.php?showtopi...t&p=1831461


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


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


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

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



Цитата(inside_pointer @  4.4.2009,  00:42 Найти цитируемый пост)

что значит зависимые операции ?

те которые имеют общий операнд.
10-2*3  // - и * зависымые и вначале выполнится умножение потом вычитание10
10-5+2*3 // - и * не зависимы друг от друга и порядок их выполнения не определен.


Цитата(inside_pointer @  4.4.2009,  00:42 Найти цитируемый пост)
почему она будет так выполняться, каким образом она проверит, что первый операнд правдив, по какому правилу ?

воэьмем пример : a && ++b; 
у ++ приоритет больше, но до нее дойдет только если а is  true
т.е вышеупомянутое  выражение разбивается на операции следующим условным образом
Код

int result = a; 
if (result)  
{ ++b;   
   result = a && b;
}


inside_pointer, и вдумайтесь так же, что написал Ln78
Цитата(Ln78 @  3.4.2009,  16:53 Найти цитируемый пост)
Это разные вещи. Если бы операция && была приоритетнее ->, то выражение, о котором был задан вопрос было бы эквивалентно:
Код

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

  smile  



Это сообщение отредактировал(а) mes - 4.4.2009, 10:26


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



****


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

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



Цитата(inside_pointer @  3.4.2009,  03:33 Найти цитируемый пост)
, - может не быть операцией

чем же operator,() отличается от operator&&() ?
PM MAIL ICQ   Вверх
zim22
Дата 4.4.2009, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


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

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



Цитата(GoldFinch @  4.4.2009,  11:59 Найти цитируемый пост)
чем же operator,() отличается от operator&&() ?

я знаю! я знаю! можно я отвечу! можно!? можно!? smile


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


Опытный
**


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

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



Цитата(mes)

10-5+2*3 // - и * не зависимы друг от друга и порядок их выполнения не определен.

это 10-5+(2*3), не определён порядок для операции +, то есть может выполниться как и умножение сначала, так и вычитание

однако не будет чего-нибудь типа 10-(5+2)*3 или ((10-5)+2)*3, то есть операции по приоритетам выстроены однозначно

Код

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

почему вот здесь, когда у && низкий приоритет, не может быть такого, что выполнится -> ? zim22, понимаешь у них приоритет разный у -> самый высокий, а у && чуть ли не как у присваивания и тут получается, что у неё приоритет не выше, чем у ->, так как, действительно, метод бы вызывался из 0 или 1, но при этом есть какое-то правило, которое выше приоритета, а формулировки его чо-то не видно, почему оно выше приоритета
PM MAIL   Вверх
GoldFinch
Дата 4.4.2009, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



Цитата(zim22 @  4.4.2009,  14:28 Найти цитируемый пост)
я знаю! я знаю! можно я отвечу! можно!? можно!?

ну и ответил бы, флудер
PM MAIL ICQ   Вверх
zim22
Дата 4.4.2009, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


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

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



Цитата(GoldFinch @  4.4.2009,  13:36 Найти цитируемый пост)
ну и ответил бы, флудер

йес!

&& - это логическая бинарная операция
, - это оператор, который используется в случаях, где ряд выражений отделяется запятыми. Выполнены будут все операнды оператора в отличии от &&, где второй операнд будет выполнен, только если первый операнд был true

А вообще это две разные операции, которые никак друг с другом не связаны. и они не взаимозаменяемы smile

Добавлено через 1 минуту и 26 секунд
Цитата(inside_pointer @  4.4.2009,  13:33 Найти цитируемый пост)
zim22, понимаешь у них приоритет разный

вы не могли бы как-то выделять обращение ко мне. а то я еле нашёл в тексте, что вы и мне отвечали.

Это сообщение отредактировал(а) zim22 - 4.4.2009, 13:41


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


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


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

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



Цитата(zim22 @  4.4.2009,  12:41 Найти цитируемый пост)
, - это оператор, который используется в случаях, где ряд выражений отделяется запятыми. Выполнены будут все операнды оператора в отличии от &&, где второй операнд будет выполнен, только если первый операнд был true

zim22GoldFinch спрашивал немножко не об этом.
Цитата(GoldFinch @  4.4.2009,  10:59 Найти цитируемый пост)
Цитата

, - может не быть операцией

чем же operator,() отличается от operator&&() ? 

его интересовало, почему "," не всегда оператор. Потому что иногда она является обычным разделителем, например в списке параметров.  smile 








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


Опытный
**


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

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



Цитата(zim22)

вы не могли бы как-то выделять обращение ко мне. а то я еле нашёл в тексте, что вы и мне отвечали.

да там инфа не важная, если пропустишь, ничо не изменится smile
PM MAIL   Вверх
mes
Дата 4.4.2009, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(inside_pointer @  4.4.2009,  12:33 Найти цитируемый пост)
это (10-5)+(2*3), не определён порядок для операции +, то есть может выполниться как и умножение сначала, так и вычитание

Как раз для + определен. Она выполнится 3й. После - и *. А вот кто из последних двух выполнится первым не определено.
А вот в выражении (10-5) && (2*3) порядок определен. Первым выполнится -, потом (если условие верно) выполнится *, и самым последним &&. 
Как видите приоретет в случае не связанных операций влияния на порядок исполнения не оказывает.

Добавлено @ 14:46
Цитата(inside_pointer @  4.4.2009,  12:33 Найти цитируемый пост)
но при этом есть какое-то правило, которое выше приоритета, а формулировки его чо-то не видно, почему оно выше приоритета 

правило которое отличает + от && в только что упомянутом примере уже цитировалось в этой теме. Попробуйте найти его сами smile

Это сообщение отредактировал(а) mes - 4.4.2009, 14:57


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


Опытный
**


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

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



Цитата(mes)

А вот в выражении (10-5) && (2*3) порядок определен. Первым выполнится -,

а, тут типа слева направо происходят все вычисления, то есть разность будет найдена самой первой, так как её приоритет выше &&, сначала не будет проверено что (10-5) истина, сначала выполнится 10-5 а потом этот результат будет проверен, так как встречается следующая операция - &&
в итоге получаем, что значения в скобках читаются, а потом выполнение выражений внутри начинается слева направо (есть там логические операции или нет)
PM MAIL   Вверх
mes
Дата 6.4.2009, 02:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(inside_pointer @  6.4.2009,  00:45 Найти цитируемый пост)

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


нет, нет и еще раз нет.
приоретет нужен всего лишь чтоб разбить на пары:

Код

так (10-5)+ (2*3) 
разбивается как
int tmp1 = 10-5; 
int tmp2 = 2*3;
int res = tmp1+tmp2;

логично предположить что для оператора && тогда должна получиться аналогичная последовательность действий

Код

итак (10-5)+ (2*3) 
по идеи должно быть :
int tmp1 = 10-5;
int tmp2 = 2*3;
bool  res = tmp1 && tmp2;

однако из за того, что компилятoр должен соблюдать правило сокращенных вычислений, получается так
Код

но предтавляется как :

int tmp1 = 10-5;
/* 
bool  res =  (tmp1) ? tmp1 
                    : tmp1 && (2*3);
так как в каждом ветвлении значение tmp1 очевидно, то запишем в более простой конструкции
*/
bool  res =  (tmp1) ? false 
                    :  (2*3);

можно подойти еще с другого конца
так например  
Код

(10-5)+ (2*3) 
это 
operator +(operator-(10,5),operator*(2,3));

а теперь попробуйте записать в такой же форме выражение (10-5)&& (2*3)  с соблюдением вышеназванного правила smile





Это сообщение отредактировал(а) mes - 6.4.2009, 02:04


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


Опытный
**


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

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



Всё, терь кое-что проясняется smile
PM MAIL   Вверх
mes
Дата 6.4.2009, 03:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата

ясно теперь, что правило какое-то есть smile

 smile 
Цитата

Unlike &, && guarantees left- to-right evaluation: the second operand is not evaluated if the  first
  operand is false.


 smile 

Это сообщение отредактировал(а) mes - 6.4.2009, 03:09


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


Опытный
**


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

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



Код

the second operand is not evaluated if the  first  operand is false

а как она проверит first operand ? как она узнает, что first  operand - это first  operand, она дойдёт до операции && после -, потому что у - приоритет выше, а у -> ещё выше, чем у -
получается эта проверка первого операнда выше всех операций, так как не выполняет второй операнд, хотя там содержится операция ->, потому что знает, что это second operand и его выполнять нельзя, пока не пройдёт проверка для first operand
PM MAIL   Вверх
mes
Дата 6.4.2009, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(inside_pointer @  6.4.2009,  09:31 Найти цитируемый пост)
а как она проверит first operand ? как она узнает, что first  operand - это first  operand, она дойдёт до операции && после -, потому что у - приоритет выше, а у -> ещё выше, чем у -
получается эта проверка первого операнда выше всех операций, так как не выполняет второй операнд, хотя там содержится операция ->, потому что знает, что это second operand и его выполнять нельзя, пока не пройдёт проверка для first operand 

проверка и сама операция && не одно и то же, это два разных действия.
грубо говоря bool res = a1 && a2, в реальности является  :
Код

bool res = (a1) ? a1 : a1 __&& a2;

где __&& "обычный"(без соблюдения правила сокращенногo вычисления) логический оператор АND .




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


Эксперт
***


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

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



Цитата(inside_pointer @  6.4.2009,  10:31 Найти цитируемый пост)
как она проверит first operand ? как она узнает, что first  operand - это first  operand, она дойдёт до операции && после -, потому что у - приоритет выше, а у -> ещё выше, чем у -

ты вообще сам читаешь что пишешь? куда оно дойдет? Приоритет операций определяется до того как вычисляются выражения. И во время определения приоритета определяется какое выражение будет операндом какой операции и после этого начинается вычисление операндов

Код

if ( a1.a && a2.a )
{
   // bla-bla
}


если уж ты хочешь с точки зрения приоритета :  a1 && a1->a  - тут && самый низкий приоритет, значит его операндами будут выражения  a1 и а1->a.   И только тут начинается вычисление операндов. Так что до операции && она дойдет намого раньше, чем начнет вычислять операнды. И какой из них правый, а какой левый компилятор всегда знает.
При реализации выражений как правило строится дерево. Корень - оператор с наименьшим приоритетом. Левая ветка - выражение левого операнда , правая - правого. Левый и правый в свою очередь такиеже  деревья начинающиеся с самой неприоритетной операции и левого и правого выражений операндов этого оператора.  Приотритет нужен для построения этого дерева и ничего при этом не вычисляется. А вычисляться начинает тогда, когда уже порядок вычисления выражения четко определен и приоритет операторов дальше уже никак ни на что не влияет.
Обходим сначала левую часть дерева - получили первый операнд. Потом обходим правую - второй. Так что никаких противоречий. 
PM MAIL   Вверх
0xDX
Дата 7.4.2009, 02:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Вообще то компилятор способен оптимизировать.........
пример
Код

if(a==5 && j)
{
//какой то прикол
}

Здесь компилятор способен увидеть что лучше проверить сначало j на ноль(так как проверка на ноль выполняется быстрее, это свойство процессора), а потом думать что делать дальше. Так же в этом примере, не имеет разницу какое условие проверять первым(логического смысла), но здругой староны эту работу должен проделать программист, на уровне привычки...........
PM MAIL   Вверх
inside_pointer
Дата 7.4.2009, 03:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Fazil6)

Корень - оператор с наименьшим приоритетом.

ну вот же оно, это правило smile
как оно следует из стандарта ? тем, что не определено обратное ?
PM MAIL   Вверх
Fazil6
Дата 7.4.2009, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(0xDX @  7.4.2009,  02:47 Найти цитируемый пост)
Вообще то компилятор способен оптимизировать.........

о, еще один... нельзя тут оптимизировать. ты читал предыдущие сообщения?


Цитата(inside_pointer @  7.4.2009,  03:28 Найти цитируемый пост)
ну вот же оно, это правило smile
как оно следует из стандарта ? тем, что не определено обратное ? 

о чем речь вообще?
какое правило? Стандарт тут причем?
Я привел пример того как в компиляторе может быть реализовано вычисление выражений. Стандарт это не определяет. Можно и подругому - главное чтобы правильно работало. В стандарте написано, что оператор && имеет фиксированный порядок вычисления аргументов отличный от обычных операторов. Как  это в компиляторе реализуют никого в стандарте не колышет. Я привел пример как можно это сделать, зачем используется приоритет и как фиксировать порядок вычисления.
PM MAIL   Вверх
inside_pointer
Дата 7.4.2009, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Fazil6)

В стандарте написано, что оператор && имеет фиксированный порядок вычисления аргументов отличный от обычных операторов.

То есть, иными словами, в стандарте написано, что правый операнд никогда не вычислится раньше левого, а дальше компиляторы могут писать как хотят и реализовывать вычисления как хотят, главное чтобы это правило работало.
Поэтому все предпочитают строить дерево от самой нижней операции, потому что так удобнее делать, а не потому что так в стандарте заложено.
PM MAIL   Вверх
Ln78
Дата 8.4.2009, 08:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(inside_pointer @  7.4.2009,  23:16 Найти цитируемый пост)
 стандарте написано, что правый операнд никогда не вычислится раньше левого, а дальше компиляторы могут писать как хотят и реализовывать вычисления как хотят, главное чтобы это правило работало.


inside_pointer, на первой странице приводили цитату из стандарта. Не просто никогда не вычисляется раньше, но и никогда не вычисляется вообще, если первый аргумент false, например, здесь
Код

   if( i >= 0 && ++j > 5 )

изменение значения j при отрицательном i никогда не должно проводиться.
PM MAIL   Вверх
mes
Дата 8.4.2009, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(inside_pointer @  7.4.2009,  02:28 Найти цитируемый пост)
Цитата

Корень - оператор с наименьшим приоритетом.
ну вот же оно, это правило smile

Есть две формы записи ариф. выражения.
1. арифметическая  a=4+b*6-c;
2. функциональная op-(op+(4,op*(b,6)),c); // где op - operator
первая нужна для удобства записи человеком, вторая для трансляции кода компилятором.
приорететы нужны, чтоб приводить первую форму записи ко второй и в дальнейшем не используются.

как видите аргументы каждой функции видны еще до начала выполнения.
для обычных функций и операторов порядок выполнения не определен, а для && требуется, ..(чтоб не повторяться см. выше в цитатах из стандарта)  smile 
 




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


Опытный
**


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

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



я понял, что он по дереву не пойдёт туда, если пройдёт в первое, если там дерево
PM MAIL   Вверх
uxoos
  Дата 21.10.2009, 01:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ещё вопрос по теме. Исключяются ли из кода пустые или бессмысленные операторы. Просто использую макросы которые оставляют такой мусор в коде.
Например, что из кода исключится, а что останется?
Код
;
5+4;
{int a;}
();
"Эта строка просто весит в коде, очень не хочется чтобы она занимала стек или что-нибудь подобное там..";

Знаю что некоторые компиляторы оптимизируют код, выявляют всегда верные условия, не используемые переменные и выдают предупреждения. И ещё, как посмотреть код с раскрытыми и заменёнными макросами?
PM MAIL   Вверх
zim22
Дата 21.10.2009, 07:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


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

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



Цитата(uxoos @  21.10.2009,  01:17 Найти цитируемый пост)
 И ещё, как посмотреть код с раскрытыми и заменёнными макросами?

ключ /P добавить в настройки проекта (С\С++-Command line-Additional options)


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


Новичок



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

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



Цитата
ключ /P добавить в настройки проекта (С\С++-Command line-Additional options)

Я добавил(Project-Options-C++Linker-Advanced-Additional options-/P), но в Builder 2010 все по обычному. smile Объясни, пожалуйста поподробнее.

Это сообщение отредактировал(а) uxoos - 21.10.2009, 20:10
PM MAIL   Вверх
zim22
Дата 21.10.2009, 20:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


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

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



Цитата(uxoos @  21.10.2009,  20:07 Найти цитируемый пост)
но в Builder 2010 все по обычному. 

smile я настройки для Microsoft Visual Studio привёл. 
они по этому пути выставляются: project properties->c/c++->preprocessor->generate preprocessed file

попробуй добавить ключ -P к опциям компилятора. где добавлять - не знаю.




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


Новичок



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

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



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


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

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