I wrote a small piece of code to understand how the offsetof macro works in the background. Here is the code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
/* Getting the offset of a variable inside a struct */
typedef struct {
int a;
char b[23];
float c;
} MyStructType;
unsigned offset = (unsigned)(&((MyStructType * )NULL)->c);
printf("offset = %u\n", offset);
return 0;
}
However, if I run it I get a warning message:
WARNING: cast from pointer to integer of different size [-Wpointer-to-int-cast]
However, if I look at the original offsetof macro in c, the code looks like this:
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
int main(void)
{
/* Getting the offset of a variable inside a struct */
typedef struct {
int a;
char b[23];
float c;
} MyStructType;
unsigned offset = offsetof(MyStructType, c);
printf("offset = %u\n", offset);
return 0;
}
So why do I get the warning as I cast to unsigned ? It appears to be the type for the offsetof macro. This is puzzling me.
As mch commented, unsigned
is not the right type; it's 32-bit on pretty much all real-world systems. The offsetof
macro is supposed to produce a result of type size_t
, which is what you "should" be casting to here. I think you're confused by the code you found storing the result into an object of type unsigned
; that's okay as long as they're sure the value is small, but it doesn't mean the type of the expression offsetof(MyStructType, c);
was unsigned
. C allows you to silently assign a larger integer type into a smaller one.
However, no matter what you do, this is not a valid implementation of offsetof
and has undefined behavior (via applying ->
to an invalid pointer). The way you get a working offsetof
without UB is #include <stddef.h>
.
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.