gcc:如何检测不良的“布尔”用法

时间:2019-03-16 15:24:54

标签: c gcc clang static-analysis

是否有某种方法可以检测类似代码中的bool值的用法错误

#include <stdbool.h>

void *foo(void)
{
    return false;
}

int bar(void)
{
    return true;
}

gcc(8.3.1)和clang(7.0.1)均接受两个功能,而没有任何警告

$ gcc -Wall -W -pedantic -c x.c
$ clang -Xclang -analyzer-checker=alpha --analyze  -Wall -W -pedantic -c x.c
$ clang -Wall -W -pedantic -c x.c
$

编译为C ++代码可以检测到foo()中的问题,但这不是一个选择,但是其余代码是C,而不是C ++。

是否有其他(-W)选项或开关会为这些情况创建诊断?

2 个答案:

答案 0 :(得分:2)

使示例不那么琐碎:

bool x;

void *foo(void)
{
    return x;
}

int bar(void)
{
    return x;
}

,它完全想编译。

通常,true和false只是定义,它们的值分别为10

来自stdbool.h头文件

#ifndef _STDBOOL_H
#define _STDBOOL_H

#ifndef __cplusplus

#define bool    _Bool
#define true    1
#define false   0

#else /* __cplusplus */

您的第一个示例中,您仅返回零,大多数编译器不会警告,因为它们将其视为NULL。尝试返回true,您将收到警告。

答案 1 :(得分:1)

C将<stdbool.h>truefalse定义为分别扩展为值10的整数常量表达式。由于它们本身是int,而bool_Bool)本身是整数类型,因此任何此类用法都同样有效。即使C语言中的布尔表达式的值也是int而不是bool,所以bar函数对您没有太大帮助。

但是,foo是另一种野兽-如果返回值是true,那么它将立即被捕获,因为1不能转换为指针。拥有整型常量值false 0 a 空指针常量,并将转换为空指针。您也许可以通过将#include <stdbool.h>替换为包含内容但将false定义为0.0的东西来代替<ol class="sortable panel-group"> <li class="panel-default"> <div class="toggle">Home</div> <div class="panel-content">Hidden content</div> </li> <li class="panel-default"> <div class="toggle">About us</div> <div class="panel-content">Hidden content</div> </li> <li class="panel-default"> <div class="toggle">Contact</div> <div class="panel-content">Hidden content</div> </li> </ol> ,这是一个伪造的值,而不是整数常量表达式。