-2

I have a function that can return a pointer to a structure or NULL (Example to explain return possibilities of get_my_struct_from_[X] functions):

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

In the main program I'm calling this function multiple times and then checking if the value is NULL or not:

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 is telling me that the if statements are redundant or there is a possible null pointer dereference.

Questions:

  1. Why does CppCheck gives me these messages?
  2. How to correctly check the return value of the function so I don't get this message

EDIT:

Forgot to mention that the my_function is an example for how the two get functions behave.

The get_my_struct_from_A and get_my_struct_from_B have different internal logic, but the output data types are the same as show in my_function. I have a lot of get_my_struct_from_X functions that I call and check the return values. So creating a new structure for each get is not an option, I don't consider that a good, because of the large amount of variables used for the same purpose.

Writing q == null or !q returns the same messages from cppcheck which is normal I think.

Czoka
  • 118
  • 3
  • 12

2 Answers2

1

Your function is supposed to return struct my_struct * and what did you return when i.value less than 5? struct my_struct.

Also if you declared the function like this you should pass a parameter which you didn't.

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

You will call it like this

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

if what you showed is what you did then there are problems/suggestions which are summarized below.

  • P Returning wrong type from the method.

  • P If get_my_struct_from_A is same as my_function in your original code then you are not passing the parameter which you should.

  • S This kind of small checkings can be done much more easily by using a function which returns true or false based the structure passed.

    bool my_function(struct my_struct ms);

user2736738
  • 28,590
  • 4
  • 37
  • 52
  • The main issue here is how this code could compile cleanly in the first place, before static analysis. – Lundin Nov 23 '17 at 15:26
  • @Lundin.: Yes I guess OP is not posting the exact code or OP changed it while posting here. Otherwise it throws me error. That's why I explicitly mentioned the points which will make OP write a compilable code. – user2736738 Nov 23 '17 at 15:27
  • @coderredoc I am not posting the exact code, I don't want a code response I want an explanation on why I'm having this problem. Added some more explanation to the question. – Czoka Nov 24 '17 at 08:18
0
struct my_struct *my_function(my_struct i) {
    if (i.value < 5) return i;

This isn't valid C (or C++) code. Your compiler is broken or incorrectly configured.

You return an integer but the function returns a pointer. The C standard is clear, C11 6.8.6.4:

If the expression has a type different from the return type of the function in which it appears, the value is converted as if by assignment to an object having the return type of the function.

Meaning that the code is equivalent to struct my_struct* tmp = i;. This can be regarded as what the C language calls "simple assignment". The rule of simple assignment C11 6.5.16.1 says that if the left operand of an assignment is a pointer, then the right operand cannot be an integer.

Thus your compiler must yield a diagnostic message for this code. If not, something is wrong with it.

Lundin
  • 155,020
  • 33
  • 213
  • 341