1

In the below code, if I print the values of union members the unassigned member int i; outputs 515. I found out that it gives the positional weight of the whole union.

Q :-But if that is declared as float i; it outputs 0.000. Any particular reason for this behaviour. How this works?

#include<stdio.h>
int main()
{
    union a
    {
        float i;
        char ch[2];
    };
    union a u;
    u.ch[0] = 3;
    u.ch[1] = 2;
    printf("%d, %d, %f\n", u.ch[0], u.ch[1], u.i);
    return 0;
}
Abhinav Kinagi
  • 3,653
  • 2
  • 27
  • 43
  • 2
    Your `union` can only hold the value of ***one-or-the-other-values*** but not both. If you give it `515` (binary `1000000011`) that make no sense as a floating point value. – David C. Rankin Jul 15 '19 at 08:14
  • 3
    https://www.geeksforgeeks.org/ieee-standard-754-floating-point-numbers/ – cdarke Jul 15 '19 at 08:15
  • [wikipedia - IEEE 754](https://en.wikipedia.org/wiki/IEEE_754) – David C. Rankin Jul 15 '19 at 08:18
  • Union size is the same as the LARGEST its' member size. – Cactus'as Jul 15 '19 at 08:29
  • 1
    size of `char[2]` is `2` (`sizeof (char[2])`); size of `i` is `sizeof i`. Do not confuse "size" with "value" – pmg Jul 15 '19 at 08:40
  • @AbhinavKinagi NO!. The largest member is `float` since it takes 4 bytes. `char [2]` takes only 2 bytes. And `union` can hold only 1 member at the time. At the time you have `chars` assigned so your `float` is unassigned and you get garbage values. That's it. That's the purpose of union, to hold multiple types of variable at the same memory space. – Cactus'as Jul 15 '19 at 08:41
  • That's not the conventional size I meant. I've edited the question – Abhinav Kinagi Jul 15 '19 at 09:21

1 Answers1

2

By using a union, this program is making two different data types (in this case, int/float and char[]) share the same memory area. Next, the program is assigning the memory area as an char and then reading it back as an int/float. This can succeed only if the value written as char, "makes sense" in the context of the data type in which it is read back. As you have observed, for "int" it might return some value as C does not apply any special encoding for integer values (but, also see twos-complement). However, real numbers are typically encoded using the IEEE754 standard and hence, the value that is read back, depends on what was decoded. I think this may be also compiler dependent as I'm seeing a "nan" (not-a-number) for the same code.

#include<stdio.h>
int main()
{
        union a
        {
                float i;
                char ch[2];
        };
        union a u;
        float f = 0.0;

        u.ch[0] = 3;
        u.ch[1] = 2;
        printf("%d, %d, %f, %f\n", u.ch[0], u.ch[1], u.i, f);
        return 0;
}

Output: 3, 2, nan, 0.000000

gsr
  • 91
  • 5
  • Yeah this answers second question. Can you solve the first? – Abhinav Kinagi Jul 15 '19 at 10:37
  • What is "positional weight of the whole union" ? Can you please share a reference as I have not come across it earlier? – gsr Jul 16 '19 at 05:06
  • That means, when you represent your union in a binary format, and adding the positions of set bits you get a number. Here it is `515` as I've explained above with a figure. – Abhinav Kinagi Jul 16 '19 at 05:14
  • 1
    In a C union, the memory for the elements is overlapping and hence, setting a member can impact the other member(s), which is also the intended use of unions (otherwise, struct would be used). You have already explained it with the figure (though it may need minor adjustment as int is typically 4 bytes). I'm not sure what is remaining as a question. – gsr Jul 16 '19 at 06:37