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){
| ~~~~~~~~~^~~~~
CodePudding user response:
First of all, you should be aware that in your program, you have two distinct variables with the name array
:
- The global variable of that name.
- 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.