Комментарии 42
в биткоин фаундейшен отправляли статью? что они сказали?
Нет, нет. Что вы. Зачем. Вдруг мы нашли настоящую уязвимость. Пусть её поиспользуют. Думаю, это будет забавно. А так — поправят тихо и всё. Не интересно.
Отправили, отправили, в конце статьи ссылка на FAQ есть
Разработчики ознакомились с отчетом и обсуждают
bitcoinstats.com/irc/bitcoin-dev/logs/2014/07/29#l1406634291
bitcoinstats.com/irc/bitcoin-dev/logs/2014/07/29#l1406634291
Подскажите доступные статические анализаторы для IDEA (Android Studio) и Xcode (Objective C).
Есть мысль, что они там особо не нужны, так как маленькие проекты очень.
Cmd+Shift+B в Xcode запускает Clang Analyzer. Вполне неплох.
Скажите, а лично Вы пользуетесь им на регулярной основе?
Да, пользуюсь. Раз в день примерно — достаточно регулярно? Единственная проблема — приходится его отключать для сторонних Cocoa Pods.
У меня лично статический анализатор включен в Xcode по-умолчанию, так как вручную я всегда забывал это сделать. Хватает ошибки-опечатки во время сборки. Сама сборка занимает чуть больше времени из-за анализа, но разница слишком маленькая, что бы мне это было критично.
Он ничего не находит даже в явно плохом коде. И часто выдает ложные срабатывания. Показался достаточно бесполезным. В IDEA, тоже, конечно, свой анализатор встроен, но кто знает, что еще для них написано?
Хм, мне он много раз подсказывал подозрительные места. -Werror -Wall -Wpedantic тоже помогают.
Какой объем проекта, который компилируете с -Werror -Wall -Wpedantic?
Включаю для новых проектов сразу же, старые править — лишь время терять. =)
По текущему проекту пока такая статистика:
По текущему проекту пока такая статистика:
$ cloc .
120 text files.
120 unique files.
10 files ignored.
http://cloc.sourceforge.net v 1.60 T=0.51 s (216.2 files/s, 10609.2 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
Objective C 55 869 442 2965
C/C++ Header 55 251 510 360
-------------------------------------------------------------------------------
SUM: 110 1120 952 3325
-------------------------------------------------------------------------------
А что clang там нашел?
«Странный цикл» — это обработка первого элемента в итерируемой коллекции.
«Это нормально» (С)
«Это нормально» (С)
и зачем тогда там цикл, если можно было бы просто взять первый элемент как и сейчас?
первого элемента может не быть
Вообще похоже что задумано так, что если в коллекции есть хотя бы 1 элемент, то функция возвращает false. Но если это так, то такой стиль программирования, мягко говоря не очень.
>Вообще похоже что задумано так, что если в коллекции есть хотя бы 1 элемент, то функция возвращает false
Не совсем. Если сработает break, то будет возвращено true.
Не совсем. Если сработает break, то будет возвращено true.
тогда для 1 элемента вместо break следовало сразу ставить return true…
Возможно и следовало бы, если бы не
1. выполнение vMasterKey = vMasterKeyIn;
2. анлок cs_KeyStore при выходе из области видимости
3. выполнение NotifyStatusChanged(this);
причем именно в этом порядке.
А уж только потом return true;
1. выполнение vMasterKey = vMasterKeyIn;
2. анлок cs_KeyStore при выходе из области видимости
3. выполнение NotifyStatusChanged(this);
причем именно в этом порядке.
А уж только потом return true;
Ну во-1х для этого предполагаются try { } finally. Но на сях его нет, это да.
тогда, имхо, надо писать так:
То есть принудительно зафиксировать однократность в заголовке.
тогда, имхо, надо писать так:
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin(); for (; mi != mapCryptedKeys.end(); mi = mapCryptedKeys.end()) { }
То есть принудительно зафиксировать однократность в заголовке.
>Ну во-1х для этого предполагаются try { } finally
Я ни в коем случае не хочу вызвать холивар, но мое стойкое убеждение, что исключения предназначены для обработки исключительных, нештатных ситуаций, и строить на них логику обработки вполне штатной ситуации — безусловное зло. Нет, доказывать не буду. Нет, доказывать мне обратное тоже не нужно :)
>Но на сях его нет, это да.
Мммм...?
>тогда, имхо, надо писать так:
Там вообще без разницы, что писать. Можно вообще for (; mi != mapCryptedKeys.end(); ) поставить — все равно выражение-инкремент ни разу не вызовется :)
А если хочется явно указать на однократность, то лучше всего это сделает не «говорящая конструкция», которую вы предложили, а не менее говорящий однострочный комментарий вроде «we'll do it only for the 1st key, if there are any» (хотя бы потому, что ваша конструкция тоже может вызвать вопрос «а на хрена оно тут, да еще и такое странное», как и текущий код).
Я ни в коем случае не хочу вызвать холивар, но мое стойкое убеждение, что исключения предназначены для обработки исключительных, нештатных ситуаций, и строить на них логику обработки вполне штатной ситуации — безусловное зло. Нет, доказывать не буду. Нет, доказывать мне обратное тоже не нужно :)
>Но на сях его нет, это да.
Мммм...?
>тогда, имхо, надо писать так:
Там вообще без разницы, что писать. Можно вообще for (; mi != mapCryptedKeys.end(); ) поставить — все равно выражение-инкремент ни разу не вызовется :)
А если хочется явно указать на однократность, то лучше всего это сделает не «говорящая конструкция», которую вы предложили, а не менее говорящий однострочный комментарий вроде «we'll do it only for the 1st key, if there are any» (хотя бы потому, что ваша конструкция тоже может вызвать вопрос «а на хрена оно тут, да еще и такое странное», как и текущий код).
finally предназначен не для исключительных ситуаций, а для обязательного исполнения завершающего кода _даже в случае исключения_.
То есть try {
…
} finally {
cleanup_there;
}
> Мммм...?
В C++ НЕТ структуры finally. Есть только try..catch.
> Там вообще без разницы, что писать.
Я говорю УБРАТЬ в конце цикла break. И оставить ТОЛЬКО mi = end().
Хотя… А в си++ будет работать вариант
if (mi!=mapCryptedKeys.end()) {
…
} while(0);
? если да — то он имхо лучше всего.
То есть try {
…
} finally {
cleanup_there;
}
> Мммм...?
В C++ НЕТ структуры finally. Есть только try..catch.
> Там вообще без разницы, что писать.
Я говорю УБРАТЬ в конце цикла break. И оставить ТОЛЬКО mi = end().
Хотя… А в си++ будет работать вариант
if (mi!=mapCryptedKeys.end()) {
…
} while(0);
? если да — то он имхо лучше всего.
В C++ есть аналог finally. Называется деструктор. На этом RAII построено.
То есть для habrahabr.ru/company/pvs-studio/blog/231489/#comment_7822513 надо заводить еще один объект, в котором определять деструктор?
По-моему мы усиливаем спагетти.
По-моему мы усиливаем спагетти.
Я не для конкретного случая, а в целом.
В конкретном случае синтаксис конечно усложнился бы, и оно того не стоит.
Хотя с С++11 лямбдами можно сделать более-менее удобно:
Код
В конкретном случае синтаксис конечно усложнился бы, и оно того не стоит.
Хотя с С++11 лямбдами можно сделать более-менее удобно:
foo() {
scope_exit([&](){
cleanup();
});
some_code();
}
cleanup
будет выполнено при выходе из функции в любом случае, независимо от исключений в основном коде.Код
scope_exit
занимает всего 5 втрочек (взято из документации буста):Скрытый текст
struct scope_exit {
scope_exit(std::function<void (void)> f) : f_(f) {}
~scope_exit(void) { f_(); }
private:
std::function<void (void)> f_;
};
P.S. Оказалось, про этот цикл уже было обсуждение: github.com/bitcoin/bitcoin/issues/4601 ( github.com/bitcoin/bitcoin/pull/4011 ).
Исходные коды взяты с помощью:
git clone https://github.com/bitcoin/bitcoin.git
Неужели так сложно написать id коммита? Плз, всегда когда берёте код из системы контоля версий, пишите id коммита
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Проверка Bitcoin