code snippet warning: cast to pointer from integer of different size

In the code snippet below, i get this warning - "warning: cast to pointer from integer of different size" in line number 25 which is the 3rd printf i do,

printf("value of a thru struct ptr=%dn",(unsigned char *)m_arr(ptr_ns_type)[0]);

I dont understand this warning since i do the same thing (except not using macros) in the 2nd printf

printf("value of a thru ptr=%dn",(unsigned char)*ptr);

for which i dont get any error. could anyone help me in understanding this warning please?

Thanks, Badri.

#include<stdio.h>
struct ns
{
    int i;
    unsigned char a[2];
};
#define m_arr(whatever)         ((struct ns *)whatever)->a
int main()
{
    unsigned char arr[2];  
    unsigned char brr[2]; 
    struct ns ns_type;
    struct ns *ptr_ns_type;
    arr[0]=192;
    arr[1]=168;
    brr[0]=172;
    brr[1]=188;

    ns_type.i=5;
    ns_type.a[0]=brr[0];
    ptr_ns_type = &ns_type;
    unsigned char *ptr=arr;
    printf("value of a=%dn",arr[0]);
    printf("value of a thru ptr=%dn",(unsigned char)*ptr);
    printf("value of a thru struct ptr=%dn",(unsigned char *)m_arr(ptr_ns_type)[0]);
    return 0;
}

You don't need a cast here:

printf("value of a thru ptr=%dn",(unsigned char)*ptr);

because ptr is a pointer to unsigned char , so *ptr is already an unsigned char .

However, here:

(unsigned char *)m_arr(ptr_ns_type)[0]

which translates to:

(unsigned char *)((struct ns *)ptr_ns_type)->a[0]

you are trying to cast unsigned char to a pointer to an unsigned char . I think what you want is:

((struct ns *)ptr_ns_type)->a[0]

but also note that the (struct ns *) cast is not necessary.


Actually, you aren't doing the same thing at all. Try getting rid of the macro, by doing the text substitution by hand. For example, lets create a variable tmp that is of type unsigned char*:

unsigned char* tmp1 = (unsigned char *)       ((struct ns *)ptr_ns_type)->a[0];

You will get the same warning. So the macro has nothing to do with it. Further, the casting is to struct ns * is superfluous and evil since it removes valuable type checking. So we can get rid of it to get clearer code:

unsigned char* tmp1 = (unsigned char *)       ptr_ns_type->a[0];

Of course, you still get the completely correct warning, but hopefulll it is now clear what is going on. When you call ptr_ns_type->a[0], you are dereferencing ptr_ns_type to obtain the array a, and using the [] operator to get the value of a[0], which is an unsigned char, and not a pointer to an unsigned char.

If you want to obtain the address of a[0], you can do so by leaving out the [0] operation:

unsigned char* tmp1 = (unsigned char *) ptr_ns_type->a;

I assume this is an exercise to help you undertand the fine points of pointers, arrays, macros and casts. Please learn the following lessons: 1. Macros are evil. Only use them when they increade the clarity of your code. 2. Avoid unecessary casting. It's unsafe. 3. Simplify, simplify. Once we simplified the code in question, the error became immediately obvious.

链接地址: http://www.djcxy.com/p/28380.html

上一篇: 警告:从指针转换为不同大小的整数

下一篇: 代码片段警告:从不同大小的整数转换为指针