如何整齐地避免C演员失去真相

时间:2010-01-21 16:01:08

标签: c coding-style

我很高兴,在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

是否可接受(对于您正在使用的任何可接受的值)?

9 个答案:

答案 0 :(得分:6)

我会在任何一种情况下调用带有(flags & INTERESTING_FLAG) != 0的func作为参数来指示需要布尔参数而不是flags & INTERESTING_FLAG的算术结果。

答案 1 :(得分:5)

我更喜欢(flags & CONST_FLAG) != 0。更好的是,如果你有它,可以使用_Bool类型(尽管它通常伪装成bool)。

答案 2 :(得分:4)

尽可能将编译器标志设置为anally,以警告任何丢失位的转换,并将警告视为错误。

答案 3 :(得分:4)

有些人不喜欢它,但我使用!!。

!!(flags & CONST_FLAG)

(不像其他人建议的to_bool宏,只是直接在代码中)。

如果有更多人使用它,它就不会被视为异常所以开始使用它!

答案 4 :(得分:1)

这可能不是一种流行的解决方案,但有时宏很有用。

#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;

总的来说,你可以花更多的时间在上面。但typedef s的宏有点傻。

答案 5 :(得分:0)

您可以通过几种不同的方式避免这种情况:

首先关闭

void func(unsigned long int);

会照顾它......

或者

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

也会这样做。

编辑:(flags & INTERESTING_FLAG) != 0也很好。可能更好。

答案 6 :(得分:0)

这部分偏离主题:

我还会创建一个帮助功能,使读者明白检查的目的是什么,这样你就不会用这个显式标志来填充你的代码。 Typedefing标志类型将使以后更容易更改标志类型和实现。

现代编译器支持内联关键字,可以摆脱函数调用中的性能开销。

typedef unsigned long int flagtype;
...
inline bool hasInterestingFlag(flagtype flags) {
   return ((flags & INTERESTING_FLAG) != 0);
}

答案 7 :(得分:0)

你有什么反对

 flags & INTERESTING_FLAG ? TRUE : FALSE

答案 8 :(得分:0)

这就是为什么当这些值具有显式布尔语义时,您应该只以“布尔”方式使用值。您的值不满足taht规则,因为它具有明显的整数语义(或者更准确地说,是位数组语义)。要将此类值转换为布尔值,请将其与0

进行比较
func((flags & INTERESTING_FLAG) != 0);