2009-08-25 5 views
3

я нашел следующее правило в coding standards sheet:C++ полагаться на неявное преобразование в bool в условиях?

Не следует полагаться на неявное преобразование к BOOL в условиях.

если (PTR) // неправильно

если (PTR! = NULL) // нормально

Как разумно/полезно есть это правило?

Сколько стоит перегрузка скомпилированного кода?

ответ

9

В строгом смысле, вы можете полагаться на неявные преобразования в bool. Обратная совместимость с C требует этого.

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

+0

Да, худшее, что кто-то следует за ним, а другие нет –

+0

Да, вы можете полагаться на неявные преобразования на' bool', так же как вы можете полагаться на приоритеты операторов, даже когда компилятор предлагает вам добавить избыточные скобки (для обоих случаев он считает, что существует нулевая проблема способность правил будет когда-либо изменяться). Вы даже можете полагаться на неявные преобразования, чтобы bool приходил и укусил вас всякий раз, когда вы забываете разыменовывать указатель в позиции, где по какой-то причине, например, перегрузка значения «bool» также имеет смысл. –

0

Это не повлияет на скомпилированный код вообще.

Что касается того, насколько он полезен - это, безусловно, поможет понять людей, поступающих с таких языков, как Java/C#. Это сделает более явным то, что вы проверяете. Это вызовет предупреждение, если вы начнете сравнивать ints с NULL (и тем самым укажете, что вы туманны относительно типа рассматриваемой переменной). Я лично предпочитаю первую форму, но это не совсем необоснованное требование.

4

В большинстве случаев это не страшно, но это может быть более читаемым, если вы набираете именно то, что вы имеете в виду.

+0

Я не могу найти ссылку сразу, но я не думаю, что вы говорите правильно. Я считаю, что стандарт определяет NULL как эквивалентный нулю. В любом случае, я не мог назвать ни одну систему, где это не так ... –

+0

NULL - 0 (до литья) на всех совместимых с удаленными стандартами системах. Некоторые эзотерические реализации могут скомпилировать указатель 0 с чем-то другим, кроме 0, но в коде все равно 0. –

+0

http://c-faq.com/null/ptrtest.html не согласен. –

0

Иногда я думаю, что это правило может быть нарушено, когда, например, работа со стандартными библиотеками, которые возвращают int вместо bool (для совместимости с C89).

Однако это правило обычно приводит к более понятному коду. Он даже применяется на таких языках, как C#, и он не жаловался на слишком много, поэтому нет никаких существенных недостатков в соблюдении этого правила, кроме как привыкнуть к нему.

0

Правило, которое добавляет нулевое преимущество, - это правило, которое вы можете выгодно удалить.

+2

Но есть преимущества, не в последнюю очередь для удобства чтения. Просто потому, что вам это не нравится, это не значит, что у него нет своих проблем. –

+0

Как это улучшает читаемость? – jalf

+0

Мне не нравится это не нравится, просто не думайте, что у него есть веские основания существовать, как правило. Вы получаете только 40 или 50 правил в стандарте управляемого кодирования - не тратьте их впустую. – soru

0

Мне не нравится это правило. В C++ идиоматично использовать неявное преобразование в bool для типов указателей (и, конечно, для булевых типов). ИМО, это гораздо легче читать

bool conditionMet = false; 

while (!conditionMet) // read as "while condition is not met" 
{ 
    /* do something */ 
} 

чем прочитать:

bool conditionMet = false; 

while (conditionMet == false) // read as "while conditionMet is false" 
{ 
    /* do something */ 
} 

Это же для указателей. Кроме того, вводя ненужное сравнение, вы вводите еще одну возможность ошибиться и получить назначение вместо сравнения, что, конечно же, приведет к нежелательным результатам. В тех случаях, когда вы используете int как bools, как и со старым C-кодом, я думаю, вы также должны использовать неявное преобразование в bool.

+1

Я бы утвердил, что для типов 'bool' он ничего не принуждает (несмотря на то, что компилятор может или не может сделать). Для типов указателей он немного серый. Что-нибудь еще, вы должны использовать оператор сравнения. –

5

Это правило связывает вас, если вы когда-либо захотите использовать класс с неявным преобразованием в bool, например std::istream. Этот код читает слово в то время из файла до EOF не будет достигнут: оператор добычи

std::ifstream file("foo.txt"); 
std::string word; 

while (file >> word) 
{ 
    // do stuff 
} 

потока возвращает ссылку на поток файла, который неявно преобразуется в bool, чтобы указать, является ли поток все еще в хорошее состояние. Когда вы дойдете до конца файла, тест завершится с ошибкой. Ваш стандарт кодирования не позволяет использовать эту общую конструкцию.

Для типов указателей это не имеет большого значения. Компилятор, вероятно, будет создавать примерно тот же код для неявного преобразования в bool и явный тест против NULL. Это вопрос вкуса в этот момент - ни один из них не «лучше» в абсолютном смысле. Стандарт кодирования просто пытается обеспечить согласованный стиль.

Учитывая это, вы должны абсолютно следовать стандарту кодирования при работе со встроенными типами (указатели, int и т. Д.). Если вы столкнетесь с аналогичной ситуацией с вышеизложенным классом, имеющим законное преобразование в bool, я бы поднял проблему с вашими товарищами по команде.

+0

Следует отметить, что есть некоторые дебаты относительно того, являются ли такие конструкции, как тот, который вы показали, хорошая идея или нет. Скрытие функциональных возможностей без преобразования для перегруженного оператора относится к категории «аккуратного трюка», но действительно ли это упрощает чтение? Или это действительно затрудняет их чтение, пока вы не узнаете об этом в библиотеке? Аналогично операторам >> и << на входных и выходных потоках - почему побитовые операции делают i/o в этом специальном случае? Это совершенно нечитаемо, пока вы не узнаете трюк. –

+0

Это онлайн-FAQ (http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.4), и это довольно распространенный код, поэтому хороший программист на C++ должен уметь понимать Это. Однако я согласен, что мы можем обсуждать его достоинства, пока корова не вернется домой. :) Это послужило удобным контрпримером для стандарта кодирования OP. –

+2

Вы все еще можете использовать эту функцию, следуя правилу: 'while (static_cast (file >> word))'. В этот момент автор стиля может захотеть изменить правило: «Не полагайтесь на неявное преобразование * по умолчанию * из указателя на bool в условиях», что, вероятно, было тем, что было предназначено в первую очередь на основе приведенного примера. Или он может потребовать, чтобы там был 'static_cast', чтобы напомнить читателям, что происходит преобразование. Вам не нужно использовать неявные преобразования, чтобы использовать конверсии. –

-3

Это впечатляюще глупое правило.

if (ptr != NULL) // ok 

, то почему бы не

if ((ptr != NULL)==true) 
+7

Потому что сравнение bools с bools просто глупо. Сравнение указателя с константой меньше. –