Как стать автором
Обновить

Комментарии 30

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

Через выкат в продакшен. Пользователи тестируют на "сломается — не сломается"

Не вижу, как эта ошибка могла на что то влиять. Поведение в обоих случаях должно быть одинаковым, если обе функции возвращают bool (на что указывает их название). Скорее просто исправили эту описку в процессе поиска реального бага.
А, там реально ошибка в том, что вторая функция вызовется в любом случае, даже если has_value() вернет false.

при этом еще и порядок вызова функций неопределён и остаётся на совести оптимизатора, в отличие от оператора &&

Человек пишет что не видит как эта ошибка могла на что-то повлиять, а не про сам факт ошибки.

То есть для того чтобы попасть в тело if , в случае с логическим "и" необходимо чтобы обе функции возвращали true. В случае с битовой операцией так же необходимо чтобы обе функции возвращали true.

То есть для пользователя по идее не должно быть разницы. Поэтому не совсем понятно на что жаловались пользователи.

Так это я сам на свой комментарий и ответил :)
Тут ситуация аналогичная такой: допустим есть указатель ptr на какой то класс, у которо есть метод foo(), возвращающий bool. Если написать
if ((ptr != nulptr) && ptr->foo())

то все будет нормально, даже если ptr будет nullptr, а если написать
if ((ptr != nullptr) & ptr->foo())

то ptr->foo() вызовется в любом случае и все упадет.

Да, ступил ) но почему упадет?

Понятно что вторая функция в данном случае будет вызываться всегда, но это не значит что вызов приведет к исключению. Хотя тут надо код смотреть

Либо я просто чего-то не знаю и если has_value() возвращает false, то label() например возвращает null

Ну выглядит так, что -> там перегруженный оператор, которые возвращает nullptr, если has_value() возвращает false. Т.е. key_data_ это что то типа какого то умного указателя, типа shared_ptr.

Да, тогда понятно... Просто я встречал иногда у некоторых коллег использование побитовых "и", но это хотя бы на сколько помню не влияло на логику приложения в целом. Хоть и выглядело паршиво. А тут гугль понимаешь... Уровень все таки... И такая хрень.

Почему не использовать плюсовый алиас and вместо &&? Тогда такие штуки можно будет поймать даже при просмотре глазами.

Потому что неявно приводить bool к int (или к какому там целочисленному типу компилятор решит привести), а потом так же неявно обратно — дурной тон, особенно в C++.
Что меня действительно напрягает — неужели у них нет никаких статических анализаторов, через которые код должен успешно пройти перед сборкой? Или у них настолько много подобных мест, что они не заметили в простыне предупреждений именно это?

Не понимаю о чем вы. Судя по заметке один из программистов случайно написал вместо && просто &. Я предположил, что использование альтернативного токена в таком случае было бы намного приемлемее для отлова ошибок. Спецификация языка прямо говорит, что между && и and нет никакой разницы:

In all respects of the language, each alternative token behaves exactly the same as its primary token…

Единичный амперсанд был единственным знаком, внесённым руками, автор принял его за простое and меж двух слов. Уровень подготовки прогеров налицо. Да, не обижайтесь. Вы работаете с тем, чего не понимаете. Потому что понять слой на слое на слое н е в о з м о ж н о. Это реалии, в которых мы живём и которыми вынуждены пользоваться. Капустный кочан, вот во что превратилось программирование со всеми этими фремворками. Любая обезьянка может создать "программу" или "сайт".

Странно, что статическим анализатором не поймали. Даже cppcheck на такое триггерится, предлагая скобки поставить, а уж всякие coverity тем более должны.

Есть подозрение что ревьювер, который это пропустил просто не сильно смотрел на код так как его отревьювили до него. А программист при мердже в релиз накосячил.

Изначальный PR. В нем все нормально.

PR который ушел в релиз. В нем амперсанд пропущен.

Вот так и появляются бэкдоры в программах.

Ага. Косяк был добавлен во втором патч-сете, вместе с какими-то фиксами. Похоже, были ошибки компиляции.


Видимо, фикс какого-то другого бага надо было мерджить в релизную ветку. Но текущая ветка далеко уже ушла и просто вставить коммит без изменений нельзя было.


А дальше — опечатка при фиксе и ревьювер, который решил второй раз "тот же самый" коммит не ревьювить.

Зачем вообще два отдельных оператора в C, разве тип операции нельзя понять из типов операндов?

У этих операций разная семантика. Упрощённо:

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

&& — Сначала всегда вычисляется только первый операнд. Если его значение приводится к false, второй операнд не вычисляется и в качестве результата выражения возвращается false. Если значение первого операнда приводится к true, вычисляется второй операнд и в качестве значения выражения возвращается значение второго операнда, приведённое к bool.

Я говорил о том, что компилятор может проверить тип опнрандов и если они оба булевы использовать логическое И с частичным вычислением и все прочим.

Если же оба операнда числовые - применять битовое И.

Если типы разные или тип результата не соответствует операции кидаем исключение.

Как это сделано в Pascal.

Всегда бесили эти && и & когда приходилось что-нибудь писать на C.

если они оба булевы использовать логическое И

так так и будет, если оба булевы, то результат & и && одинаков.


Всегда бесили эти && и & когда приходилось что-нибудь писать на C.

на момент изобретения си возможность писать a && b вместо (a != 0) && (b != 0) казалось очень классной идеей.
всё-таки с тех пор очень много лет прошло.

А зачем усложнять компилятор и ухудшать читабельность кода? То, что логическая операция с частичным выполнением и числовая битовая операция с полным выполнением обозначаются разными символами — совершенно правильное решение. Другое дело — слабая типизация C/C++, нивелирующая преимущества этого решения.

В классическом Pascal есть только логический AND. То, что в современных реализациях AND можно применять к числам — уродливая самодеятельность «улучшателей» языка.

Не, не согласен, никогда в Pascal не было с этим затруднений.

Наверное дело привычки.

Не знаток различных языков программирования, поэтому вопрос «первоклассника»:
Как обстоят дела с возможностью допустить такую простую ошибку/опечатку (& vs &&) в других ЯП?
В Java, JavaScript, PHP замена && на & не вызовет ошибки — код выполнится.
В Go замена && на & вызовет ошибку компиляции.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Другие новости

Истории