我很高兴,在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
答案 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);