1

I need to check if an element of an array of pointers is NULL or not. I tried to write the code as following, but the compiler gives me an error.

struct Example {
    float number1;
    int number2;
};
typedef struct Example Example;

static Example *array[3] = { NULL }; //inizialized array to NULL

    for (int i = 0; i < 3; i++) {
        if (array[i] == NULL) {
            /*code*/
            break;
        }
    }

This is the error I get:

"error: invalid operands to binary == (have ‘Example’ and ‘void *’)"

referred to the line

 if (array[i] == NULL) {

What am I doing wrong?

UPDATE

The for loop was originally inside another function that took as parameter the array of pointers.

static void fun(Example *array) {
    for (int i = 0; i < 3; i++) {
        if (array[i] == NULL) {
            /*code*/
            break;
        }
    }
}

But it keeps giving me the same error, despite the fact that the type is actually Example* and not Example. Instead, if I write Example** array as parameter, it accepts the code and doesn't give me any error.

static void fun (Example **array) {
    for (int i = 0; i < 3; i++) {
        if (array[i] == NULL) {
            /*code*/
            break;
        }
    }
}

Can someone explain to me why does the compiler wants Example** and not Example* ?

FULL CODE

Here's the full code, in 2 files: file.c and file.h.

file.h:

#include <stdio.h>
#include <stdbool.h>

struct Example {
    float number1;
    int number2;
};
typedef struct Example Example;

file.c

#include <stdio.h>
#include <stdlib.h>
#include "file.h"

static Example *array[3] = { NULL }; //inizialized array to NULL
static void fun(Example *);

static void fun(Example *array) {
    for (int i = 0; i < 3; i++) {
        if (array[i] == NULL) {
            /*code*/
            break;
        }
    }
}

int main(void) {
    fun(array);
    return 0;
}

ERROR:

gcc -c file.c -std=c11 -Wall
file.c: In function ‘fun’:
file.c:10:28: error: invalid operands to binary == (have ‘Example’ and ‘void *’)
   10 |                if(array[i] == NULL){
      |                   ~~~~~~~~ ^~
      |                        |
      |                        Example
file.c: In function ‘main’:
file.c:20:9: warning: passing argument 1 of ‘fun’ from incompatible pointer type [-Wincompatible-pointer-types]
   20 |     fun(array);
      |         ^~~~~
      |         |
      |         Example **
file.c:8:26: note: expected ‘Example *’ but argument is of type ‘Example **’
    8 | static void fun(Example* array){
      |                 ~~~~~~~~~^~~~~
5
  • 2
    Maybe you are using a C++ compiler? [Hint: dont!] Commented Dec 25, 2021 at 0:42
  • 2
    Please show stackoverflow.com/help/mcve -- the code as is compiles without warnings. Commented Dec 25, 2021 at 1:31
  • 1
    How are you compiling this? Using a C++ compiler? Your code is correct C. You may have intentionally or unintentionally used used a C++ compiler, if it's intentionally stop doing so and if it's unintentionally, correct your mistake. Commented Dec 25, 2021 at 2:44
  • There is a missmatch between the error message and the code you are showing. array[i] is of type Example *, but the error message claims that it is of type Example Commented Dec 25, 2021 at 10:35
  • Yes, I'm using a C compiler. I updated the question for more details, I really don't get what I'm doing wrong... Commented Dec 25, 2021 at 19:45

1 Answer 1

3

First of all, you should be aware that in your program, you have two distinct variables with the name array:

  1. The global variable of that name.
  2. The local variable (function parameter) of the function fun.

Inside the function fun, the local variable array will shadow the global variable of the same name, which means that when you write array inside that function, you will be referring to the local variable, not the global variable. To prevent any confusion, you may want to use different names for both variables.

The compiler is complaining about the following line:

if(array[i] == NULL){

As previously stated, using the identifier array inside the function fun will refer to the function parameter, not the global variable.

In the function definition of fun, you defined the type of the function parameter array to be Example *. Therefore, dereferencing this type using array[i] will give you a variable of type Example. This means that in array[i] == NULL, you are attempting to compare a struct Example with the value NULL. This does not make sense, and is also the reason why are you getting the compiler error.

Instead of defining the function parameter array to be of type Example*, you probably want it to be of type Example**, because you want it to point to the first element of the array, which is itself a pointer to a struct Example. In other words, you want the function parameter to be a pointer to a pointer. Therefore, you should also declare it as such:

static void fun( Example **array ){

Or maybe better:

static void fun( Example *array[] ){

Both of these lines are equivalent as far as the compiler is concerned, but the second line is maybe better, as it makes clear that the pointer is not pointing to a single variable, but rather to an array.

The expression array[i] == NULL now makes sense, as it will now compare an Entity* with NULL.

After applying this change to the function definition of fun, and after also applying it to the forward declaration of the function, your code will compile cleanly.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.