Как аккуратно избежать бросков C, теряющих истину

Я довольно рад, что в C вещами как это является плохой код:

(var_a == var_b) ? TRUE : FALSE

Однако что является лучшим способом иметь дело с этим:

/* Header stuff */
#define INTERESTING_FLAG 0x80000000
typedef short int BOOL;

void func(BOOL);

/* Code */
int main(int argc, char *argv[])
{
        unsigned long int flags = 0x00000000;

        ... /* Various bits of flag processing */

        func(flags & INTERESTING_FLAG); /* func never receives a non-zero value
                                         * as the top bits are cut off when the
                                         * argument is cast down to a short 
                                         * int
                                         */
}

Действительно ли это приемлемо (для любого значения приемлемых, которые Вы используете) иметь (flags & FLAG_CONST) ? TRUE : FALSE?

5
задан me_and 21 January 2010 в 17:53
поделиться

9 ответов

Я бы предпочел (флаги и const_flag)! = 0 . Все еще лучше, используйте тип _bool, если у вас есть (хотя он часто замаскирован как Bool ).

5
ответ дан 18 December 2019 в 07:54
поделиться

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

4
ответ дан 18 December 2019 в 07:54
поделиться

Некоторые люди не нравятся, но я использую !!

IE

!!(flags & CONST_FLAG)

(не как макрос TO_BOOL как кто-то еще предложен, просто прямо в коде).

Если его использовали больше людей, он не был бы замечен как необычный , поэтому начните использовать его !!

4
ответ дан 18 December 2019 в 07:54
поделиться

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

#define to_bool(x) (!!(x))

Теперь мы можем безопасно иметь все, что захотим, не опасаясь переполнения нашего типа:

func(to_bool(flags & INTERESTING_FLAG));

Другой альтернативой может быть определение вашего булевого типа как intmax_t (из stdint.h), так что невозможно усечь значение до фальшивости.

Пока я здесь, я хочу сказать, что вы должны использовать typedef для определения нового типа, а не #define:

typedef short Bool; // or whatever type you end up choosing

Некоторые могут возразить, что вы должны использовать переменную const вместо макроса для числовых констант:

const INTERESTING_FLAG = 0x80000000;

В целом, есть вещи и получше, на которые вы можете потратить свое время. Но макросы для typedefs немного глупые.

1
ответ дан 18 December 2019 в 07:54
поделиться

Вы можете избежать этого пары разных способов:

во-первых.

void func(unsigned long int);

позаботится об этом ...

или

if(flags & INTERESTING_FLAG)
{
  func(true);
}
else
{
  func(false);
}

также сделает это.

Редактировать: (Флаги и интересные_flag)! = 0 также хорошо. Наверное лучше.

0
ответ дан 18 December 2019 в 07:54
поделиться

Это частично выключено в тему:

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

Современные компиляторы поддерживают ключевое слово Inline, которое может избавиться от накладных расходов производительности в вызове функций.

typedef unsigned long int flagtype;
...
inline bool hasInterestingFlag(flagtype flags) {
   return ((flags & INTERESTING_FLAG) != 0);
}
0
ответ дан 18 December 2019 в 07:54
поделиться

Вот почему вы должны использовать значения только в «логическом» пути, когда эти значения имеют явную булевую семантику. Ваша стоимость не удовлетворяет правилу TAHT, поскольку он имеет выраженную целочисленную семантику (или, точнее, семантику битовой массивы). Чтобы преобразовать такое значение для логика, сравните его с 0

func((flags & INTERESTING_FLAG) != 0); 
0
ответ дан 18 December 2019 в 07:54
поделиться

Я бы в любом случае вызвала func с (flags & INTERESTING_FLAG) != 0 в качестве аргумента для указания, что необходим булевый параметр, а не арифметический результат flags & INTERESTING_FLAG.

6
ответ дан 18 December 2019 в 07:54
поделиться

У вас есть что-нибудь против

 flags & INTERESTING_FLAG ? TRUE : FALSE

?

0
ответ дан 18 December 2019 в 07:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: