LocalHost
LocalHost

Reputation: 910

Trying to print structure variable without dot operator

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

Answers (4)

John Bode
John Bode

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 );

  1. Per the C 2011 Online Draft, 6.2.7.1/15: "Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning."

Upvotes: 1

chux
chux

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

yano
yano

Reputation: 5275

Based on the output, I know that your machine is little endian and has 4 byte ints.

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

89f3a1c
89f3a1c

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 int
  • printf("%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

Related Questions