0

I'm new in C. Let's say i have a union.

union DP 
{ 
  int c[3]; 
  char a[3][4]; 
  short b[2]; 
}point = {256,258,260}; 

printf("%i",point.a[0][1]); 
printf("%i",point.a[1][2]);
printf("%i",point.a[2][0]); 

Why does the first print give 1 and second give 0 and third give 4?

haccks
  • 104,019
  • 25
  • 176
  • 264

4 Answers4

3

You can initialize only one member of a union at a time. Elements of c (first member) is initialized here1. Members of a and b are uninitialized. Accessing uninitialized variables invokes undefined behavior. You may get either expected or unexpected results.

n1570: Annex J: J.2 Undefined behavior

The behavior is undefined in the following circumstances:
...
— An lvalue designating an object of automatic storage duration that could have been declared with the register storage class is used in a context that requires the value of the designated object, but the object is uninitialized (6.3.2.1).


1: Other member can be initialized using C99's designated initializers

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
  • Your first sentence was really short, now it's a little clearer however i would add an example to show what you mean. – fonZ Aug 06 '14 at 14:46
  • I think accessing the 'wrong' members of an union is implementation-defined behavior instead of undefined behavior. Can't quote chapter and verse though. – pdw Aug 06 '14 at 14:55
  • @pdw; See the the reference. – haccks Aug 06 '14 at 15:01
  • @pdw: It's more complicated with unions. It was defined a little vague in C99, and less vague in C11. But the intent is rather clear: Unions can be used for type-punning, so accessing a member after another member was assigned to, is usually OK (if this doesn't result in a trap representation among other things). Cf. C11 6.5.2.3 p.4 (including the footnote), 6.2.6.1 p.6 et seqq. – mafso Aug 06 '14 at 19:04
  • 1
    @haccks, that citation doesn't apply here, as the union is initialized. See 6.2.6.1.7: "When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that member but do correspond to other members take unspecified values." Note that it says "*take unspecified values*": all bytes of the union are initialized, and the "extra" bytes are merely unspecified, not undefined. – pdw Aug 06 '14 at 19:55
3

Considering that you've made a union (quite strange btw), it's quite straightforward to give the reason since you initialize the variable point as an array of 3 ints (first field of your union):

  • a[0][1] is the 2nd byte of the 1st number, 256. In hexadecimal notation, this int is 0x00000100, so 2nd byte is 0x01 -> value is 1.
  • a[1][2] is the 3rd byte of the 2nd number, 258. In hexadecimal notation, this int is 0x00000102, so 3rd byte is 0x00 -> value is 0.
  • a[2][0] is the 1st byte of the 3rd number, 260. In hexadecimal notation, this int is 0x00000104, so 3rd byte is 0x04 -> value is 4.
mafso
  • 5,433
  • 2
  • 19
  • 40
Bentoy13
  • 4,886
  • 1
  • 20
  • 33
0

Two big problems:

  1. The maximum positive value that can be assigned to a char is (most likely) either 128 or 256, depending on if it's signed or unsigned.

  2. You are not assigning values to point.a correctly. It must be done as follows:

    point = {.a[0][1] = 256, .a[1][2] = 258, .a[2][0] = 260};
    

The following works as expected:

union DP 
{ 
    int c[3]; 
    char a[3][4]; 
    short b[2]; 
} point = {.a[0][1] = 'a', .a[1][2] = 'b', .a[2][0] = 'c'}; 

printf("%c",point.a[0][1]); 
printf("%c",point.a[1][2]);
printf("%c",point.a[2][0]);

abc

Edit

If your intent is to assign values to point.c, you do something very similar to what's mentioned above:

point = {.c[0] = 256, .c[1] = 258, .c[2] = 260};

or...

point = {.c[0] = 256, 258, 260};
Fiddling Bits
  • 8,712
  • 3
  • 28
  • 46
0

If you want to initialize Matrixes and Vectors, you have to initialize them one by one, and complete the unusued spaces with zero, otherwise it should not initialize. I refactored your code, try that and see what happens, I'm not sure what is the objective of your code.

union DP 
{ 
  int c[3]; 
  char a[3][4] = {256,258,260,0,0,0,0,0,0,0,0,0,0}; //This will generate an overflow, char characters max value is 255 each (1 byte)
  short b[2]; 
}point;

printf("%i",point.a[0][1]); //This printf will show this value as Integer type, if this compiles
printf("%i",point.a[1][2]); 
printf("%i",point.a[2][0]);
raphaelbgr
  • 179
  • 3
  • 10