Home > Net >  Why is clang throwing these warnings?
Why is clang throwing these warnings?

Time:04-09

user@thisbox Tests % make ./null_a_ptr 
cc     null_a_ptr.c   -o null_a_ptr
null_a_ptr.c:17:20: warning: incompatible pointer to integer conversion assigning to 'size_t' (aka 'unsigned long') from 'int *' [-Wint-conversion]
                myarray[i].pthis = &p;
                                 ^ ~~
null_a_ptr.c:22:24: warning: comparison between pointer and integer ('size_t' (aka 'unsigned long') and 'void *') [-Wpointer-integer-compare]
                if (myarray[i].pthis != NULL) {
                    ~~~~~~~~~~~~~~~~ ^  ~~~~
null_a_ptr.c:30:20: warning: incompatible pointer to integer conversion assigning to 'size_t' (aka 'unsigned long') from 'void *' [-Wint-conversion]
                myarray[i].pthis = NULL;
                                 ^ ~~~~
null_a_ptr.c:35:24: warning: comparison between pointer and integer ('size_t' (aka 'unsigned long') and 'void *') [-Wpointer-integer-compare]
                if (myarray[i].pthis != NULL) {
                    ~~~~~~~~~~~~~~~~ ^  ~~~~
4 warnings generated.
user@thisbox Tests % ./null_a_ptr     
sizeof(&p) is 8
myarray[0].pthis is initially not NULL
myarray[1].pthis is initially not NULL
myarray[0].pthis is finally NULL
myarray[1].pthis is finally NULL
user@thisbox Tests 

In reality, mystruct describes a calloc-ed array (address & element count). sizeof(element) is known elsewhere. There may be up to 20 such calloc-ed arrays (real-world #define MAGIC 20), but some will be empty/emptied ...hence the desire to set a NULL pointer.

My code appears to work, but QUESTIONS:

These warnings clutter up compile reports: How to get rid of?

Is is portable to assume size_t pthis always initialises to NULL? (it does with Clang on M1 Mac)

Code needs to compile & run on M1 Mac and Win(whatever is current). M1 Mac compiler throwing these warnings is Clang.

Thanks for any ideas, Chris

Code to replicate:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAGIC 2

struct mystruct {
    size_t pthis;
    int thiscnt;
};
struct mystruct myarray[MAGIC];

int main(void) {
    int p = 1234; // just to get a pointer
    printf("sizeof(&p) is %lu\n", sizeof(&p));
    for (int i = 0; i < MAGIC; i  ) {
        myarray[i].pthis = &p;                // <<<<< WARNING
    }
    for (int i = 0; i < MAGIC; i  ) {
        printf("myarray[%d].pthis is initially ", i);
        if (myarray[i].pthis != NULL) {       // <<<<< WARNING
            puts("not NULL");
        }
        else {
            puts("NULL");
        }
    }
    for (int i = 0; i < MAGIC; i  ) {
        myarray[i].pthis = NULL;              // <<<<< WARNING
        myarray[i].thiscnt = 0;
    }
    for (int i = 0; i < MAGIC; i  ) {
        printf("myarray[%d].pthis is finally ", i);
        if (myarray[i].pthis != NULL) {.      // <<<<< WARNING
            puts("not NULL");   
        }
        else {
            puts("NULL");
        }
    }
    return 0;
}

CodePudding user response:

You're getting a warning because you're attempting to assign a pointer value to an integer type. Don't do that.

Instead, change the pthis member to have type int * to match what you're assigning to it.

CodePudding user response:

If you want to store an address into a non-pointer type variable, use uintptr_t type.

That said, use %zu to print the result of sizeof operator, as it's of type size_t.

  •  Tags:  
  • c
  • Related