C的if()条件中==(!=)运算符的LHS或RHS中的MACRO?

时间:2018-12-13 21:29:02

标签: c if-statement operators preprocessor

这是我在分析大型代码库时的观察结果。这是示例代码

/*comparing received RAT(it may be 2G/3G/4G) Type from ip packet with numeric value */
if(pBearer.data.recv.rat_recv == 1)
{
        rrc.send_conn.rat_type = MY_GERAN; /* setting RAT as GERAN(enumerated value) i.e 2G */
        /* further processing of packet */
}

这是代码审查者的评论

  

根据编码标准,我们应该使用MACRO而不是数值   一段时间后,我们可能会使用=而不是==

它解析为

if(pBearer.data.recv.rat_recv == DB_RAT_GERAN) /* DB_RAT_GERAN is a macro defined somewhere in header file */
{
        rrc.send_conn.rat_type = MY_GERAN; /* setting RAT as GERAN i.e 2G */
        /* further processing of packet */
}

这是正确的,因为有时可能会错误地使用=而不是像

那样使用==
if(pBearer.data.recv.rat_recv = 1) { /* always set RAT as 2G */ }

并且编译器不会产生任何警告(好的编译器,可能是,但是几乎没有人分析makebuild的结果,直到崩溃)或相同的错误并产生了问题。

现在我这里有了古玩,可以像这样使用

if(DB_RAT_GERAN == pBearer.data.recv.rat_recv)

而不是

if(pBearer.data.recv.rat_recv == DB_RAT_GERAN)

我更喜欢在比较运算符的手而不是右手使用MACRO,因为在最坏的情况下,如果错误地使用=代替==下面

if(DB_RAT_GERAN = pBearer.data.recv.rat_recv){ }

编译器会产生一个非常有意义的错误,例如

  

错误:左值必须作为赋值的左操作数

但是这个

if(pBearer.data.recv.rat_recv = DB_RAT_GERAN) { }

简单地逃脱。

建议使用以上两种方法中的哪一种,甚至使用更好的技术,C标准中是否有关于相同内容的说明,即在比较算子的LHS中应在检查中还是在RHS方面使用MACRO?

1 个答案:

答案 0 :(得分:5)

使用if (a == 5)还是if (5 == a)之类的东西在很大程度上取决于样式。 C标准没有说明建议的条件用法。

尽管后者(通常称为“ Yoda条件句”)实际上可以防止错误地使用=而不是==(这正是您提到的代码审查评论所指的内容) ,但是这种风格不容易阅读。

如今,大多数编译器都将发出警告。特别是,如果您使用-Wall,gcc将对此发出警告,而MSVC将使用/W4进行警告。只要您将警告级别设置得足够高(您始终应该这样做)并将警告视为错误(对于gcc,-Werror,对于MSVC,/WX)就可以将其视为错误不要错过,我建议您使用这种样式,以提高可读性和适用于这种情况的工具。