please see my codes below
#include <stdio.h>
#include <stddef.h>
typedef struct _node
{
int a;
char *s;
}Node, *nodePtr;
int main(int argc, char *argv[])
{
char *str = "string"; /*str points to satic storage area*/
Node nd;
nodePtr pNode = NULL;
size_t offset_of_s = offsetof(Node,s);
nd.a = 1;
nd.s = str;
pNode = &nd;
/*Get addr of s, cast it to a different data types pointer, then de-reference it*/
/*this works, print "string"*/
printf("%s\n", *(int*)((char*)pNode + offset_of_s));
/*this sucks, print (null)*/
printf("%s\n", *(float*)((char*)pNode + offset_of_s));
return 0;
}
i attempt to get the address of the s member of the Node structure, cast it to a data types not less than 4 bytes(4 byte is the width of a pointer on my machine), then de-reference the pointer as a argument to printf.
i do think the outcome of two printfs should be the same, but the second one displays “(null)” .
float and int have the same byte width on my machine, is the internal different representation of the two types that cause this ?
thanks in advance !
Your program invokes undefined behavior because the types of the arguments to
printf()are not what printf expects. There is no way to predict the outcome by looking at the source code.C99-TC3,
§7.19.6.1/9However, if you are interested in the reason the behavior you’ve observed is as it is, it’s likely that your compiler is one of those that pass floating-point values to printf() in the floating-point CPU registers. (GNU and CLang do that, for example). The second call to printf placed the dereferenced value in a floating-point register, but
printf, seeing the%sconversion specifier, looked at the register where achar*would have been passed, likely a general-purpose register, which happened to be zero in your case.PS: Here’s what GCC 4.6.1 makes out of it on my linux
Same story with clang 2.9