简体   繁体   中英

Why do I get warnings when I try to assign the address of a variable to a pointer that was declared to point to a variable of a different type?

Take a look at the following program. What I don't understand is why do I have to cast the address of the variable x to char* when it actually would be absolutely useless if you think about it for a second. All I really need is only the address of the variable and all the necessary type information is already in place provided by the declaration statement char* ptr .

#include <stdio.h>


int main(void) {
    int   x   = 0x01020309;
    char* ptr = &x; /* The GCC compiler is going to complain here. It will
                       say the following: "warning: initialization from
                       incompatible pointer type [enabled by default]". I
                       need to use the cast operator (char*) to make the
                       compiler happy. But why? */

    /* char* ptr = (char*) &x; */ /* this will make the compiler happy */

    printf("%d\n", *ptr); /* Will print 9 on a little-endian machine */


    return 0;
}

The C Standard , , paragraph 28 states: 第28段规定:

A pointer to void shall have the same representation and alignment requirements as a pointer to a character type. Similarly, pointers to qualified or unqualified versions of compatible types shall have the same representation and alignment requirements. All pointers to structure types shall have the same representation and alignment requirements as each other. All pointers to union types shall have the same representation and alignment requirements as each other. Pointers to other types need not have the same representation or alignment requirements.

Since different types of pointers can have differing implementations or constraints, you can't assume it's safe to convert from one type to another.

For example:

char a;
int *p = &a

If the implementation has an alignment restriction on int , but not on char , that would result in a program that could fail to run.

This is because pointers of different types point to blocks of memory of different sizes even if they point to the same location.

&x is of type int* which tells the compiler the number of bytes (depending on sizeof(int) ) to read when getting data. Printing *(&x) will return the original value you entered for x

Now if you just do char* ptr = &x; the compiler assigns the address in &x to your new pointer (it can as they are both pointers) but it warns you that you are changing the size of the block of memory being addressed as a char is only 1 byte. If you cast it you are telling the compiler that this is what you intend. Printing *(ptr) will return only the first byte of the value of x .

According to your code, x is of type int . So the pointer that points to x should be of type int * . Compiler gives such error because you use a pointer which is not int * .

So make your pointer either int * , or void * then you don't need cast.

Its just simple as you assign integer type to character. similarly you are trying to assign integer type pointer to character type pointer.

Now why is so because this is how c works, if you increment a character pointer it will give you one byte next address and incrementing integer pointer will give you 2 byte next address.

You are correct that it makes no practical difference. The warning is there to inform you that there might be something fishy with that assignment.

C has fairly strong type-checking, so most compilers will issue a warning when the types are not compatible.

You can get rid of the warning by adding an explicit cast (char*) , which is you saying:

I know what I'm doing, I want to assign this value to my char* pointer even if the types don't match.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM