MISRA C:2012 规则 14.4
MISRA C:2012 Rule 14.4
根据 MISRA 规则
if 语句的控制表达式和迭代语句的控制表达式本质上应具有布尔类型
#include <stdbool.h>
#include <stdlib.h>
void foo(void){
int i = 0;
if(i){} /* Non-compliant - int32_t is not boolean */
if(i != 0){} /* Compliant */
}
我不明白为什么只使用值会导致问题。为什么只添加布尔表达式被视为良好做法。
任何见解都会有所帮助
我想不出具体原因。
我在考虑类型转换,例如使用 double d
可能会出错,但 double 将被评估为 be/not 为 0.0,因此仍然是 if 或迭代语句的有效表达式。或指向字符(字符串)的指针,但它也会产生有效的表达式。
所以我能想到的唯一原因是现在很清楚它是一个布尔表达式,即更好的可读性。
如果 MISRA 也能检查正确的第二个操作数就更好了,例如
char *s;
if (s != NULL && *s != '[=10=]')
也可以写成:
if (s != 0 && *s != 0)
和双 d
:
if (d != 0.0)
Why with if only adding a boolean expression is treated as good practise?
"MISRA-C 引入了强类型模型来帮助用户避免在 C 类型模型中发生的意外问题。
该规则可防止在需要布尔表达式时意外使用整数表达式。
“ 作为 stated in the MISRA forum, as an "official" MISRA C WG answer
How can it lead to a problem to just use a integer in a if statement?
我想不出办法,但是在项目中执行一致的代码风格和理念也很重要。
另一个可能的原因可能是识别像这样的潜在错误:
#include <stdbool.h>
#include <stdlib.h>
void foo(void){
int i = 0;
if(i){} /* Non-compliant - int32_t is not boolean */
if(i |= 0){} /* Non-compliant - type is still int32_t */
}
或更明显的
#include <stdbool.h>
#include <stdlib.h>
void foo(void){
int i = 0;
if(i){} /* Non-compliant - int32_t is not boolean */
if(i = 0){} /* Non-compliant */
}
规则提供了基本原理:强类型。控制表达式本质上应该是布尔类型。相等、关系等运算符的结果被视为本质上是布尔值,而在没有运算符的 int
或指针中显示意味着表达式属于所使用的类型。
(作为旁注,这对于与 C++ 的兼容性可能很重要,其中许多运算符实际上 return 一个 bool
,并且可能会被 operator
函数重载returning bool
.)
然而,MISRA 并未提供主要原因,那就是自文档化代码。 if(ptr != NULL)
只能是指针与 NULL 的比较。没有误解的余地。 if(ptr)
可能是与 NULL 的比较,也可能是手指的意外失误,而程序员实际上是指 if(*ptr)
。此外,如果指针有一些神秘的名称,则 if(xyz)
的作用并不明显,但 if(xyz != NULL)
的作用很明显。
此规则还可以防止诸如 if(func)
之类的错误,其中 if(func())
是有意的。请记住,许多 MISRA 规则都是为了静态分析器的好处。
关于强类型,考虑这个例子:
#include <stdio.h>
#include <stdbool.h>
int main (void)
{
int x = false;
x = ~x;
if(x)
{
puts("x is true");
if(x!=true)
{
puts("but x is not true\n");
}
}
bool y = x;
if(y)
{
puts("y is true");
if(y==true)
{
puts("I swear, y is really true");
}
}
}
输出:
x is true
but x is not true
y is true
I swear, y is really true
根据 MISRA 规则 if 语句的控制表达式和迭代语句的控制表达式本质上应具有布尔类型
#include <stdbool.h>
#include <stdlib.h>
void foo(void){
int i = 0;
if(i){} /* Non-compliant - int32_t is not boolean */
if(i != 0){} /* Compliant */
}
我不明白为什么只使用值会导致问题。为什么只添加布尔表达式被视为良好做法。 任何见解都会有所帮助
我想不出具体原因。
我在考虑类型转换,例如使用 double d
可能会出错,但 double 将被评估为 be/not 为 0.0,因此仍然是 if 或迭代语句的有效表达式。或指向字符(字符串)的指针,但它也会产生有效的表达式。
所以我能想到的唯一原因是现在很清楚它是一个布尔表达式,即更好的可读性。
如果 MISRA 也能检查正确的第二个操作数就更好了,例如
char *s;
if (s != NULL && *s != '[=10=]')
也可以写成:
if (s != 0 && *s != 0)
和双 d
:
if (d != 0.0)
Why with if only adding a boolean expression is treated as good practise?
"MISRA-C 引入了强类型模型来帮助用户避免在 C 类型模型中发生的意外问题。 该规则可防止在需要布尔表达式时意外使用整数表达式。 “ 作为 stated in the MISRA forum, as an "official" MISRA C WG answer
How can it lead to a problem to just use a integer in a if statement?
我想不出办法,但是在项目中执行一致的代码风格和理念也很重要。
另一个可能的原因可能是识别像这样的潜在错误:
#include <stdbool.h>
#include <stdlib.h>
void foo(void){
int i = 0;
if(i){} /* Non-compliant - int32_t is not boolean */
if(i |= 0){} /* Non-compliant - type is still int32_t */
}
或更明显的
#include <stdbool.h>
#include <stdlib.h>
void foo(void){
int i = 0;
if(i){} /* Non-compliant - int32_t is not boolean */
if(i = 0){} /* Non-compliant */
}
规则提供了基本原理:强类型。控制表达式本质上应该是布尔类型。相等、关系等运算符的结果被视为本质上是布尔值,而在没有运算符的 int
或指针中显示意味着表达式属于所使用的类型。
(作为旁注,这对于与 C++ 的兼容性可能很重要,其中许多运算符实际上 return 一个 bool
,并且可能会被 operator
函数重载returning bool
.)
然而,MISRA 并未提供主要原因,那就是自文档化代码。 if(ptr != NULL)
只能是指针与 NULL 的比较。没有误解的余地。 if(ptr)
可能是与 NULL 的比较,也可能是手指的意外失误,而程序员实际上是指 if(*ptr)
。此外,如果指针有一些神秘的名称,则 if(xyz)
的作用并不明显,但 if(xyz != NULL)
的作用很明显。
此规则还可以防止诸如 if(func)
之类的错误,其中 if(func())
是有意的。请记住,许多 MISRA 规则都是为了静态分析器的好处。
关于强类型,考虑这个例子:
#include <stdio.h>
#include <stdbool.h>
int main (void)
{
int x = false;
x = ~x;
if(x)
{
puts("x is true");
if(x!=true)
{
puts("but x is not true\n");
}
}
bool y = x;
if(y)
{
puts("y is true");
if(y==true)
{
puts("I swear, y is really true");
}
}
}
输出:
x is true
but x is not true
y is true
I swear, y is really true