Использование !!, &* и подобного
От: _pk_sly  
Дата: 01.07.18 09:44
Оценка: 2 (1) -2
Всем привет!

Кто как относится к использованию таких, как бы, операторов в C++ как "!!", "&*" и подобных? (а кстати, каких?)

У меня на работе возник спор. Мои коллеги, опытные С++ программисты, сказали мне, что они смотрят на эти знаки в упор и вообще не понимают, что это такое.

Между тем, например, оператор ! является не просто логическим "не", но другая его важная функция — преобразование аргумента в bool. Вот так вот, одним символом. Другое дело — что он от этого bool делает ещё и отрицание, а вот чтобы просто преобразовать в bool, крайне удобно использовать !!.
Если у вас там, например, указатель или число или вообще — класс, а то и шаблон и вам надо получить bool, !! — крайне удобная штука. Пользуюсь уже этим, чтобы не соврать, лет 15.

Ну или вот &*. Есть у нас любого вида smart pointer. Для примера возьмём unique_ptr. Для того, чтобы программист не запутался, неявная конверсия — запрещена. Зато, есть оператор *.
Ну и что же у нас получается? Удобный способ получить ссылку на значение — есть, а вот чтобы получить указатель, надо вызывать специальный метод .get().
Тут поможет &*.
Ну а в макросах и шаблонах эта штука и вовсе — незаменима. Независимо, передали туда настоящий указатель или класс, это сработает.

Наверняка есть и другие удобные штуки, но этими я пользуюсь постоянно.

Как думает сообщество, действительно ли это — какая-то нечитаемая непонятная хрень, которой не стоит пугать людей или же нормальная техника C++?

Речь не идёт об обфускации или приколах типа "оператор стремления -->".
с++ operator macros templates
Re: Использование !!, &* и подобного
От: T4r4sB Россия  
Дата: 01.07.18 09:55
Оценка:
Здравствуйте, _pk_sly, Вы писали:

__>Между тем, например, оператор ! является не просто логическим "не", но другая его важная функция — преобразование аргумента в bool.


x!=0
Re: Использование !!, &* и подобного
От: andrey.desman  
Дата: 01.07.18 10:11
Оценка: 7 (3) +8
Здравствуйте, _pk_sly, Вы писали:

__>Наверняка есть и другие удобные штуки, но этими я пользуюсь постоянно.


Например if (!~ioctl()).
Как тебе, навскидку?

__>Как думает сообщество, действительно ли это — какая-то нечитаемая непонятная хрень, которой не стоит пугать людей или же нормальная техника C++?


Эти штуки прикольные, но они отвлекают от сути. Приходится напрягаться и вчитываться. До тех пор, пока этим не пользуются все, т.е. пока оно не станет очередным шаблоном, который мозг воспринимает автоматически, лучше так не писать. Т.е. либо все так пишут, либо никто, если мы говорим о командной разработке.
Re: Использование !!, &* и подобного
От: Dair Россия https://dair.spb.ru
Дата: 01.07.18 16:13
Оценка: 1 (1) +5 -1
Здравствуйте, _pk_sly, Вы писали:

__>Между тем, например, оператор ! является не просто логическим "не", но другая его важная функция — преобразование аргумента в bool. Вот так вот, одним символом. Другое дело — что он от этого bool делает ещё и отрицание, а вот чтобы просто преобразовать в bool, крайне удобно использовать !!.

__>Если у вас там, например, указатель или число или вообще — класс, а то и шаблон и вам надо получить bool, !! — крайне удобная штука. Пользуюсь уже этим, чтобы не соврать, лет 15.

Ужас какой.

Чтобы получить bool, надо сделать (bool).


__>Ну и что же у нас получается? Удобный способ получить ссылку на значение — есть, а вот чтобы получить указатель, надо вызывать специальный метод .get().

__>Тут поможет &*.

И get() запомнится с третьего раза, а конструкция &* — с сто третьего. Ещё не знаю как там в венде, но если на get() можно кликнуть и перейти посмотреть что он делает, то с &* такое не прокатывает.

__>Как думает сообщество, действительно ли это — какая-то нечитаемая непонятная хрень, которой не стоит пугать людей или же нормальная техника C++?


Это нечитаемся непонятная хрень, усложняющая чтение кода.
Re: Использование !!, &* и подобного
От: smeeld  
Дата: 01.07.18 16:59
Оценка:
Здравствуйте, _pk_sly, Вы писали:

__>Всем привет!


__>Кто как относится к использованию таких, как бы, операторов в C++ как "!!", "&*" и подобных? (а кстати, каких?)


Подобные штуки пользуют те, кому они нравятся, кому не нравятся-не используют. Это дело вкуса, и если это вкусы ключевых разрабов или тимлидов, то эти вкусы превращаются в свод правил кодестайла, которые эти штуки могут запрещать или разрешать. Мне, как старому сишнику, начинавшему кодить с Си и асма в в vi и unix-е, эти штуки понятны и приятны. Но встречал кучу народа, у которых они вызывают крайне негативную реакцию, эти предпочитают обёртывать всё в читабельные функции типа get_some_name, cast_to_some_type.
Re: Использование !!, &* и подобного
От: a7d3  
Дата: 01.07.18 17:28
Оценка:
Здравствуйте, _pk_sly, Вы писали:

__> Пользуюсь уже этим, чтобы не соврать, лет 15.


Нет смысла этими «удобными штуками» пользоваться.
С моей стороны тоже лет 20 стажа наберётся и последние 15 лет идёт однозначный тренд на крайне простой код с небольшими функциями, влезающими на один экран. А не только на agile, открытость и социальную адаптированность работчиков — не только IQ, но и хорошо развитые EQ, SC.

Иногда приходится сталкиваться с «разработчиками» из провинций/регионов (всяких научно-промышленных кластеров экс-СССР) и их творчеством. Хорошо видно, что именно их этот самый тренд обошёл стороной и по широкой дуге. В московским/питерских компаниях иногда тоже встречается, но в совсем стрёмных шарашках, давно застывших во времени и непонятно куда дрейфующих в пространстве.
Re: Использование !!, &* и подобного
От: mbait  
Дата: 01.07.18 22:56
Оценка:
Про "!!" слышал, но на практике в Си никогда не сталкивался с необходимостью им использоваться. В С++ же нужно использовать приведение типов и вообще стараться не использовать "магию".

Про "&*" никогда не слышал, но на интуитивном уровне чувствуется, что этот приём "попахивает". При взаимной проверке кода я бы попросил заменить на .get() или вообще пересмотреть контракты так, чтобы с сырым указателям не нужно было работать вообще.
Re: Использование !!, &* и подобного
От: VladFein США  
Дата: 01.07.18 23:07
Оценка:
Здравствуйте, _pk_sly, Вы писали:

__>Кто как относится к использованию таких, как бы, операторов в C++ как "!!", "&*" и подобных? (а кстати, каких?)


Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?

Brian Kernighan
Re[2]: Использование !!, &* и подобного
От: Pzz Россия https://github.com/alexpevzner
Дата: 01.07.18 23:12
Оценка: 1 (1)
Здравствуйте, andrey.desman, Вы писали:

AD>Например if (!~ioctl()).

AD>Как тебе, навскидку?

Я б получающийся код сравнил.

!! — это, в некотором смысле, идеоматическое выражение, и компилятор его, скорее всего, знает, и соптимизирует. Я вот !~ — это экзотика, и компилятор вряд ли будет его оптимизировать.
Re[2]: Использование !!, &* и подобного
От: Pzz Россия https://github.com/alexpevzner
Дата: 01.07.18 23:14
Оценка: +1
Здравствуйте, mbait, Вы писали:

M>Про "!!" слышал, но на практике в Си никогда не сталкивался с необходимостью им использоваться.


Современные компиляторы стали поругиваться, когда в качестве bool'а используешь не bool.
Re[2]: Использование !!, &* и подобного
От: Pzz Россия https://github.com/alexpevzner
Дата: 01.07.18 23:16
Оценка:
Здравствуйте, VladFein, Вы писали:

VF>

Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?

VF>Brian Kernighan

Лучше бы он это Ритчи с Томпсоном сказал, когда они придумывали язык, в котором такое можно написать...
Re[3]: Использование !!, &* и подобного
От: VladFein США  
Дата: 01.07.18 23:30
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Лучше бы он это Ритчи с Томпсоном сказал, когда они придумывали язык, в котором такое можно написать...


Какое "такое"? Приминение оператора отрицания (!) к boolean? Повторное?
Re[4]: Использование !!, &* и подобного
От: Pzz Россия https://github.com/alexpevzner
Дата: 01.07.18 23:32
Оценка:
Здравствуйте, VladFein, Вы писали:

Pzz>>Лучше бы он это Ритчи с Томпсоном сказал, когда они придумывали язык, в котором такое можно написать...


VF>Какое "такое"? Приминение оператора отрицания (!) к boolean? Повторное?


Ну, например, применение оператора ! к не-boolean. Впрочем, в том Си и булеонов-то никаких не было...
Re: Использование !!, &* и подобного
От: Nikе Россия  
Дата: 02.07.18 01:19
Оценка:
Здравствуйте, _pk_sly, Вы писали:

__>а то и шаблон и вам надо получить bool, !! — крайне удобная штука. Пользуюсь уже этим, чтобы не соврать, лет 15.

Аналогичный срок использую. Раньше было актуальнее, когда булы часто были тайпдефами от интов — нужно было для нормализации значения.

__>Ну или вот &*. Есть у нас любого вида smart pointer. Для примера возьмём unique_ptr. Для того, чтобы программист не запутался, неявная конверсия — запрещена. Зато, есть оператор *.

get лучше, так как разыменование нулевого указателя — это UB. На практике конечно работало.
Нужно разобрать угил.
Re[2]: Использование !!, &* и подобного
От: _pk_sly  
Дата: 02.07.18 07:53
Оценка: +2
D>Чтобы получить bool, надо сделать (bool).

Нет-нет, что вы. Это в Си так делали.
А в C++ православный способ:
static_cast<bool>(val)

Совершенно другой набор знаков, не так ли?
Re[2]: Использование !!, &* и подобного
От: _pk_sly  
Дата: 02.07.18 07:57
Оценка:
__>>Как думает сообщество, действительно ли это — какая-то нечитаемая непонятная хрень, которой не стоит пугать людей или же нормальная техника C++?

AD>Эти штуки прикольные, но они отвлекают от сути. Приходится напрягаться и вчитываться. До тех пор, пока этим не пользуются все, т.е. пока оно не станет очередным шаблоном, который мозг воспринимает автоматически, лучше так не писать. Т.е. либо все так пишут, либо никто, если мы говорим о командной разработке.


Я совершенно согласен, что писать надо понятно, но понятность — вовсе не фича языка, а то, к чему привыкло сообщество. Паскалистам вон понятнее begin и end писать

Собсно, моя цель и заключается в том, чтобы выяснить, интуитивно-понятно ли это сообществу.
Re[2]: Использование !!, &* и подобного
От: Кодт Россия  
Дата: 02.07.18 08:44
Оценка: 1 (1)
Здравствуйте, Dair, Вы писали:

D>Чтобы получить bool, надо сделать (bool).


си-каст бывает забанен в code style. Например, в гугловском.
Поэтому и приходится делать оператор пыщь-пыщь — особенно, в тех случаях, когда вместо bool есть unspecified_bool.
#include <gtest.h>
#include <memory>
#include <boost/shared_ptr.hpp>  // тяжёлое наследие, библиотеки эпохи C++03-

TEST_F(TheTest, TheCase) {
  std::shared_ptr<int> s(new int());
  ASSERT_TRUE(s);

  boost::shared_ptr<int> b(new int());
  ASSERT_TRUE(b);  // не скомпилируется, потому что это шаблонное ASSERT_EQ(true, actual_value), ошибка сопоставления типов
  ASSERT_TRUE(b != nullptr);  // запрещено кодстайлом: используйте ASSERT_NE, а про него см.выше
  ASSERT_TRUE(static_cast<bool>(b));  // ой фууу
  ASSERT_FALSE(!b);  // отрицание отрицания, единство и борьба противоположностей, ошибкоопасный с т.з. понимания код
  ASSERT_TRUE(!!b);  // так себе ок, но ок
}
Перекуём баги на фичи!
Re[3]: Использование !!, &* и подобного
От: galileo Земля  
Дата: 02.07.18 09:15
Оценка: +1
Здравствуйте, _pk_sly, Вы писали:

__>Нет-нет, что вы. Это в Си так делали.

__>А в C++ православный способ:
__>
__>static_cast<bool>(val)
__>

__>Совершенно другой набор знаков, не так ли?

Некоторые еще любят переменные называть одной буквой, причем все, тоже говорят меньше текста получается.
Хотя компилятор стерпит, работает же...
Но если ты работаешь с людьми, и им приходится иметь дело с твоим кодом, то пожалуйста делай код более читабельным, даже если он получается больше.
А всякую магию лучше применять там где без нее нельзя.
Re[3]: Использование !!, &* и подобного
От: andrey.desman  
Дата: 02.07.18 09:35
Оценка:
Здравствуйте, Pzz, Вы писали:

AD>>Например if (!~ioctl()).

AD>>Как тебе, навскидку?

Pzz>Я б получающийся код сравнил.


В первую очередь интересно, как оно воспринимается, а не что компилятор там нагенерит — все равно крохи.

Pzz>!! — это, в некотором смысле, идеоматическое выражение, и компилятор его, скорее всего, знает, и соптимизирует. Я вот !~ — это экзотика, и компилятор вряд ли будет его оптимизировать.


Ой, да что тут оптимизировать? not, jz. Это "!= -1" как раз должен оптимизироваться в !~.
Re[4]: Использование !!, &* и подобного
От: Pzz Россия https://github.com/alexpevzner
Дата: 02.07.18 17:43
Оценка:
Здравствуйте, andrey.desman, Вы писали:

Pzz>>!! — это, в некотором смысле, идеоматическое выражение, и компилятор его, скорее всего, знает, и соптимизирует. Я вот !~ — это экзотика, и компилятор вряд ли будет его оптимизировать.


AD>Ой, да что тут оптимизировать? not, jz. Это "!= -1" как раз должен оптимизироваться в !~.


Ну, например, если оно в if'е стоит, то очень вероятно, что можно обойтись без nоt'a. А если требуется именно булевское значение, его вычисление тоже можно по-разному расписать.
Re[5]: Использование !!, &* и подобного
От: andrey.desman  
Дата: 02.07.18 17:51
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>>>!! — это, в некотором смысле, идеоматическое выражение, и компилятор его, скорее всего, знает, и соптимизирует. Я вот !~ — это экзотика, и компилятор вряд ли будет его оптимизировать.

AD>>Ой, да что тут оптимизировать? not, jz. Это "!= -1" как раз должен оптимизироваться в !~.
Pzz>Ну, например, если оно в if'е стоит, то очень вероятно, что можно обойтись без nоt'a.

Можно загрузить 0xffffffff и проверить and или cmp, но меньше, чем через not, не нагенеришь кода.
Re: Использование !!, &* и подобного
От: rm822 Россия  
Дата: 02.07.18 19:11
Оценка: 1 (1)
Здравствуйте, _pk_sly, Вы писали:

__>Всем привет!


__>Кто как относится к использованию таких, как бы, операторов в C++ как "!!", "&*" и подобных? (а кстати, каких?)

нормально, они привычные, хотя и постепенно уходят из употребления
~0, ^ — тоже ничего так, полезненько
скоро будет еще и <=>
Re[3]: Использование !!, &* и подобного
От: andyp  
Дата: 02.07.18 21:58
Оценка:
Здравствуйте, _pk_sly, Вы писали:

__>Совершенно другой набор знаков, не так ли?


Ну делай так тогда: bool(val)
Re[2]: Использование !!, &* и подобного
От: _NN_ www.nemerleweb.com
Дата: 04.07.18 10:27
Оценка:
Здравствуйте, Nikе, Вы писали:

__>>Ну или вот &*. Есть у нас любого вида smart pointer. Для примера возьмём unique_ptr. Для того, чтобы программист не запутался, неявная конверсия — запрещена. Зато, есть оператор *.

N>get лучше, так как разыменование нулевого указателя — это UB. На практике конечно работало.
Чем get будет лучше ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Использование !!, &* и подобного
От: Nikе Россия  
Дата: 04.07.18 12:04
Оценка:
Здравствуйте, _NN_, Вы писали:

N>>get лучше, так как разыменование нулевого указателя — это UB. На практике конечно работало.

_NN>Чем get будет лучше ?

Это официальный способ и без уб.
Нужно разобрать угил.
Re[4]: Использование !!, &* и подобного
От: _NN_ www.nemerleweb.com
Дата: 04.07.18 13:14
Оценка:
Здравствуйте, Nikе, Вы писали:

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


N>>>get лучше, так как разыменование нулевого указателя — это UB. На практике конечно работало.

_NN>>Чем get будет лучше ?

N>Это официальный способ и без уб.

&* такой же официальный способ.
А каким образом нет неопределенного поведения ?

unique_ptr<int> a;
int i = *a.get();
int j = *a;
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: Использование !!, &* и подобного
От: Nikе Россия  
Дата: 04.07.18 13:22
Оценка:
Здравствуйте, _NN_, Вы писали:

N>>Это официальный способ и без уб.

_NN>&* такой же официальный способ.
Нет.

_NN>А каким образом нет неопределенного поведения ?

Не распарсил.

_NN>
_NN>unique_ptr<int> a;
_NN>int i = *a.get();
_NN>int j = *a;
_NN>

Не в тему, где тут аналог &*?

UB возникает из-за возможного разыменования nullptr;
Нужно разобрать угил.
Re[6]: Использование !!, &* и подобного
От: _NN_ www.nemerleweb.com
Дата: 04.07.18 13:24
Оценка: -1
Здравствуйте, Nikе, Вы писали:

_NN>>А каким образом нет неопределенного поведения ?

N>Не распарсил.

_NN>>
_NN>>unique_ptr<int> a;
_NN>>int i = *a.get();
_NN>>int j = *a;
_NN>>

N>Не в тему, где тут аналог &*?

Так вот же разыменовывание нулевого указателя перед глазами: *a.get()
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[7]: Использование !!, &* и подобного
От: _NN_ www.nemerleweb.com
Дата: 05.07.18 07:09
Оценка:
Здравствуйте, _NN_, Вы писали:

Попробую разжевать.
Итак внимательно следим

template <class T, class D>
class unique_ptr
{
T* p;

public:
T* get() const
{
  return p;
}

T& operator*() const
{
  return *p;
}
}


*a == a.operator*() == *(a.p)
*a.get()== *(a.get()) == *(a.p)

Разницы нет, что и требовалось доказать.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[8]: Использование !!, &* и подобного
От: Nikе Россия  
Дата: 05.07.18 07:25
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Разницы нет, что и требовалось доказать.


Разыменование невалидного указателя это UB. В операторе * ты делаешь это. UB означает, что ситуация может быть развиваться так как ты ожидаешь, но может и диск отформатировать.
Нашёл такой пример:
struct S { int some_field; };

void do_something(S* p)
{
  // Несмотря на то, что мы всего лишь берём адрес поля,
  // а не обращаемся к его значению -- формально мы выполняем разыменование,
  // т.е. в случае p == nullptr имеем UB.
  int *field_ptr = &p->some_field;
  // ...
  // Т.к. выше в случае p == nullptr имеем UB, компилятор может
  // оптимизировать код с предположением, что p != nullptr (для случая без UB!)
  // и убрать эту проверку как лишнюю.
  if (p != nullptr)
  {
     // Код в этом блоке может быть выполнен даже если p == nullptr.
     // ...
  }
}
Нужно разобрать угил.
Re[9]: Использование !!, &* и подобного
От: _NN_ www.nemerleweb.com
Дата: 05.07.18 07:27
Оценка:
Здравствуйте, Nikе, Вы писали:

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


_NN>>Разницы нет, что и требовалось доказать.


N>Разыменование невалидного указателя это UB. В операторе * ты делаешь это. UB означает, что ситуация может быть развиваться так как ты ожидаешь, но может и диск отформатировать.

Хорошо, а чем в этом плане отличается функция 'get' ?
*a.get() также может разыменовывать невалидный указатель.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[10]: Использование !!, &* и подобного
От: Nikе Россия  
Дата: 05.07.18 07:29
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Хорошо, а чем в этом плане отличается функция 'get' ?

Тем что она не содержит UB преобразуя умный указатель в обычный.

_NN>*a.get() также может разыменовывать невалидный указатель.

Это уже будет UB, но оно будет на совести пользователя.
Нужно разобрать угил.
Re[11]: Использование !!, &* и подобного
От: _NN_ www.nemerleweb.com
Дата: 05.07.18 07:37
Оценка: +1 :)
Здравствуйте, Nikе, Вы писали:

Перечитал снова и наконец понял что с чем сравнивается.
&* vs. get

Если так сравнивать, то конечно get более верный способ.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Использование !!, &* и подобного
От: fk0 Россия https://fk0.name
Дата: 19.07.18 07:43
Оценка:
Здравствуйте, _pk_sly, Вы писали:


__>Кто как относится к использованию таких, как бы, операторов в C++ как "!!", "&*" и подобных? (а кстати, каких?)


__>У меня на работе возник спор. Мои коллеги, опытные С++ программисты, сказали мне, что они смотрят на эти знаки в упор и вообще не понимают, что это такое.


опытные программисты насиженное место, job security...

__>Наверняка есть и другие удобные штуки, но этими я пользуюсь постоянно.


__>Как думает сообщество, действительно ли это — какая-то нечитаемая непонятная хрень, которой не стоит пугать людей или же нормальная техника C++?


Код валидный и понятный. Спорить не о чём.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.