Reputation: 910
I am trying to print a structure variable simply without any dot or arrow operator.
#include<stdio.h>
int main()
{
struct test{
char A[10];
float b;
}obj = {"Testing",3.14};
printf("%u\n",&obj);
printf("%u\n",&obj.A);
printf("%u\n",obj);
}
OUTPUT
6422288
6422288
1953719636
See the third printf statement. I am simply trying to print the value of obj
. Now i know it is something i am not supposed to do but i was just curious. The above two statements are simply printing the start address of the structure variable(assuming there is no pre structure padding involved here) but i am unable to understand what is happening in case 3. If it was an array of structure than simply writing obj
would provide the base address of that array but what is the logic here ?
Upvotes: 0
Views: 296
Reputation: 123558
The address of the first element of a struct
is the same as the address of the struct
object itself1, so if you interpret the address of obj
as a char *
, then you can print the string stored in the first member like so:
printf( "%s\n", (char *) &obj );
However...
While tricks like this may give you some insight into how things work under the hood, they should be avoided in "real " code. Life is easier for everyone if you use the member access operators as intended:
printf( "%s\n", obj.A );
Upvotes: 1
Reputation: 154146
Its all undefined behavior (UB)
printf("%u\n",&obj);
is UB as a pointer is not spec'd to match "%u"
. Same for other 2. All UB.
but i am unable to understand what is happening in case 3
Recall that using a mis-matched print specifier is UB and can lead to non-sense output as the parameter passing mechanisms can differ by type. E.g. A FP value is passed in a FP stack and not the usual one resulting is %u
accessing random data.
I recommend to use matching specifiers like "%p"
for addresses, hex specifiers for numbers ("%X"
"%a"
) and hex constants (0x123, 1.23p45) when trying to divine UB.
#include<stdio.h>
int main() {
struct test {
char A[10];
float b;
} obj = { "Testing", 3.14p0 };
printf("%p\n", (void *) &obj);
printf("%p\n", (void *) &obj.A);
// Still UB, but if you get some output, possible easier to correlate to what is happening on your machine.
printf("%llX\n", obj);
}
Upvotes: 4
Reputation: 5275
Based on the output, I know that your machine is little endian and has 4 byte int
s.
In ASCII "Testing" is { 0x54, 0x65, 0x73, 0x74 ... }
. When you tell printf
to use the %u
format specifier for unsigned int
, it looks at the first 4 bytes of the "value" of obj
. Interpretted as little endian, this is 0x74736554, which in base 10 is 1953719636, the value you see output.
Upvotes: 1
Reputation: 1488
printf("%u\n",&obj);
prints the address where the struct starts, interpreted as an unsigned int.printf("%u\n",&obj.A);
prints the addres of obj.A, interpreted as an unsigned intprintf("%u\n",obj);
prints the value of the struct, interpreted as an unsigned int.Anyway, following this question's advice, for printing pointer values it's better to use %p
.
Upvotes: 2