cppcheck空指针取消引用,但它实际上可以变为null

时间:2017-11-23 15:03:19

标签: c null-pointer cppcheck

我有一个函数可以返回指向结构的指针或NULL(示例来解释 get_my_struct_from_ [X] 函数的返回可能性):

struct my_struct *my_function(my_struct i) {
    if (i.value < 5) return i;
    else return NULL;
}

在主程序中,我多次调用此函数,然后检查值是否为NULL:

struct my_struct *q;
q = get_my_struct_from_A();
if (q == NULL) {
    // display an error message and exit
}

q = get_my_struct_from_B();
if (q == NULL) {
    // display an error message and exit
}

CppCheck告诉我if语句是冗余的,或者可能存在空指针解除引用。

问题:

  1. 为什么CppCheck会给我这些消息?
  2. 如何正确检查功能的返回值,以便我不会收到此消息
  3. 修改

    忘记提及my_function是两个get函数行为的示例。

    get_my_struct_from_A和get_my_struct_from_B具有不同的内部逻辑,但输出数据类型与my_function中显示的相同。我有很多我调用的get_my_struct_from_X函数并检查返回值。因此,为每个获取创建一个新结构不是一种选择,我不认为这是一个好的,因为用于相同目的的大量变量。

    q == null!q会从cppcheck返回相同的消息,我认为这是正常的。

2 个答案:

答案 0 :(得分:1)

你的函数应该返回struct my_struct *,当i.value小于5时你返回了什么? struct my_struct

此外,如果你声明了这样的函数,你应该传递一个你没有的参数。

struct my_struct *my_function(struct my_struct* i) {
    if (i->value < 5) return i;
    else return NULL;
}

你会这样称呼它

struct my_struct a;
...
struct my_struct *q = my_function(&a);
if( !q ){
   // it returned NULL
}

如果您所展示的是您所做的,则会出现以下概述的问题/建议。

  • P 从方法中返回错误的类型。

  • P 如果get_my_struct_from_A与原始代码中的my_function相同,则表示您没有传递应该使用的参数。

  • S 通过使用根据传递的结构返回true或false的函数,可以更轻松地完成这种小型检查。

    bool my_function(struct my_struct ms);

答案 1 :(得分:0)

struct my_struct *my_function(my_struct i) {
    if (i.value < 5) return i;

这不是有效的C(或C ++)代码。您的编译器已损坏或配置不正确。

返回一个整数,但该函数返回一个指针。 C标准清楚,C11 6.8.6.4:

  

如果表达式有   类型不同于它出现的函数的返回类型,值为   通过赋值给具有函数返回类型的对象进行转换。

意思是代码等同于struct my_struct* tmp = i;。这可以被视为C语言称之为“简单赋值”的东西。简单赋值的规则C11 6.5.16.1表示如果赋值的左操作数是指针,则右操作数不能是整数。

因此,您的编译器必须为此代码生成诊断消息。如果没有,那就有问题了。