двойное отрицание по стандарту
От: Antikrot  
Дата: 27.12.04 14:51
Оценка: 1 (1)
Нашел недавно (в исходниках xvid'а) такое выражение:
   mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);

Далее это используется как индекс в массиве из двух элементов.
То, что в скобках, имеет значения или 0 или 2^11, и путем такого преобразования превращается в 0 или 1. (все переменные здесь типа int)
Собственно, взяло сомнение, хотя это и работает, но как это будет по стандарту?
Не получится ли так, что компилятор использует не единичку в качестве отрицания нуля, а что-нибудь другое, и мы получим вылет за пределы массива?
Re: двойное отрицание по стандарту
От: Vamp Россия  
Дата: 27.12.04 14:53
Оценка: -1
Имхо, undefined behaviour.
Да здравствует мыло душистое и веревка пушистая.
Re: двойное отрицание по стандарту
От: korzhik Россия  
Дата: 27.12.04 14:54
Оценка:
Здравствуйте, Antikrot, Вы писали:

A>Нашел недавно (в исходниках xvid'а) такое выражение:

A>
A>   mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
A>

A>Далее это используется как индекс в массиве из двух элементов.
A>То, что в скобках, имеет значения или 0 или 2^11, и путем такого преобразования превращается в 0 или 1. (все переменные здесь типа int)
A>Собственно, взяло сомнение, хотя это и работает, но как это будет по стандарту?
A>Не получится ли так, что компилятор использует не единичку в качестве отрицания нуля, а что-нибудь другое, и мы получим вылет за пределы массива?

Всё будет нормально.
Известный трюк.

4.12 Boolean conversions
1 An rvalue of arithmetic, enumeration, pointer, or pointer to member type can be converted to an rvalue of
type bool. A zero value, null pointer value, or null member pointer value is converted to false; any
other value is converted to true.

Re[2]: двойное отрицание по стандарту
От: Кодт Россия  
Дата: 27.12.04 14:59
Оценка: +2
Здравствуйте, Vamp, Вы писали:

V>Имхо, undefined behaviour.


Очень даже defined.
Любые целые числа, перечисления и указатели приводятся к bool (для первого оператора !), а bool — всегда 0 (false) и 1 (true).
Перекуём баги на фичи!
Re[2]: двойное отрицание по стандарту
От: korzhik Россия  
Дата: 27.12.04 15:01
Оценка: 2 (1)
Здравствуйте, korzhik, Вы писали:

K>4.12 Boolean conversions
K>1 An rvalue of arithmetic, enumeration, pointer, or pointer to member type can be converted to an rvalue of
K>type bool. A zero value, null pointer value, or null member pointer value is converted to false; any
K>other value is converted to true.


И вот ещё:

4.5-4
An rvalue of type bool can be converted to an rvalue of type int, with false becoming zero and true
becoming one.

Re: двойное отрицание по стандарту
От: Bell Россия  
Дата: 27.12.04 15:04
Оценка:
Здравствуйте, Antikrot, Вы писали:


4.7 Integral conversions
...
4.7/4
If the destination type is bool, see 4.12. If the source type is bool, 
the value false is converted to zero and the value true is converted to one.

...

4.12 Boolean conversions
1. An rvalue of arithmetic, enumeration, pointer, or pointer to member type 
can be converted to an rvalue of type bool. A zero value, null pointer value, 
or null member pointer value is converted to false; any other value is converted to true.


Так что беспокоится не о чем.
Любите книгу — источник знаний (с) М.Горький
Re[3]: двойное отрицание по стандарту
От: Vamp Россия  
Дата: 27.12.04 15:05
Оценка:
К>... а bool — всегда 0 (false) и 1 (true).

Не знал.
Да здравствует мыло душистое и веревка пушистая.
Re: двойное отрицание по стандарту
От: Imbecile Россия  
Дата: 27.12.04 15:32
Оценка:
Здравствуйте, Antikrot, Вы писали:

A>Нашел недавно (в исходниках xvid'а) такое выражение:

A>
A>   mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
A>

A>Далее это используется как индекс в массиве из двух элементов.
A>То, что в скобках, имеет значения или 0 или 2^11, и путем такого преобразования превращается в 0 или 1. (все переменные здесь типа int)
A>Собственно, взяло сомнение, хотя это и работает, но как это будет по стандарту?
A>Не получится ли так, что компилятор использует не единичку в качестве отрицания нуля, а что-нибудь другое, и мы получим вылет за пределы массива?

Ну вообще-то всё правильно,
значение выражения pParam->vol_flags & XVID_VOL_MPEGQUANT инвертируется два раза
допустим с какого-то числа в ноль, а из нуля в 1,
или из 0 в 1, а потом из 1 в ноль.
Re: двойное отрицание по стандарту
От: MaximE Великобритания  
Дата: 28.12.04 07:43
Оценка:
Antikrot wrote:

> Нашел недавно (в исходниках xvid'а) такое выражение:

>
>    mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);
>


Оно тождественно такому:

mpeg = 0 != (pParam->vol_flags & XVID_VOL_MPEGQUANT);


[]

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


Нет, все ok. В C результатом ! является int(0) или int(1). В C++ для встроенных типов — bool(false) или bool(true), bool(false) == int(0), bool(true) == int(1) (§4.5.5).

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9 delta
Re: двойное отрицание по стандарту
От: Rakafon Украина http://rakafon.blogspot.com/
Дата: 31.08.09 14:30
Оценка: +1 -2 :))
Здравствуйте, Antikrot, Вы писали:
A>Нашел недавно (в исходниках xvid'а) такое выражение:
A> mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);

... понятно, что это чужие исходники, там-то уж ничего не поменять, но так писать самому я б не рекомендовал ... трюк конечно known, но, ИМХО, код получается нечитабельный, думаю, что лучше писать так:
mpeg = static_cast<bool>(pParam->vol_flags & XVID_VOL_MPEGQUANT);
"Дайте мне возможность выпускать и контролировать деньги в государстве и – мне нет дела до того, кто пишет его законы." (c) Мейер Ансельм Ротшильд , банкир.
Re[3]: двойное отрицание по стандарту
От: dcb-BanDos Россия  
Дата: 02.09.09 14:38
Оценка: :)
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Vamp, Вы писали:


V>>Имхо, undefined behaviour.


К>Очень даже defined.

К>Любые целые числа, перечисления и указатели приводятся к bool (для первого оператора !), а bool — всегда 0 (false) и 1 (true).

то что 0 это false — понятно, а можно из станадрта что-либо, показывающее , что true — это 1 ?
Ничто не ограничивает полет мысли программиста так, как компилятор.
Re[4]: двойное отрицание по стандарту
От: Кодт Россия  
Дата: 02.09.09 16:41
Оценка: +1 :))
Здравствуйте, dcb-BanDos, Вы писали:

DB>то что 0 это false — понятно, а можно из станадрта что-либо, показывающее , что true — это 1 ?


Пять лет назад, в этой же ветке... Re[2]: двойное отрицание по стандарту
Автор: korzhik
Дата: 27.12.04
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.