Static initialization of unions containing arrays etc. (casting)

A

anon.asdf

Hi!

I am not succeeding in (statically) initializing a variable of the
following type:

union myunion {
short arr2[4];
int arr4[2];
};

Code attempt (with compilation errors):
/**********************/

#include <stdio.h>

union myunion {
short arr2[4];
int arr4[2];
};

short arr2_v[4] = \
{1, 2, 3, 4};

union myunion mu_v1 = \
(union myunion) arr2_v;
/** ??? **/

union myunion mu_v2 = \
(union myunion) \
(short [4]) {5, 6, 7, 8};
/** ??? **/

union myunion mu_arr_v3[1] = \
{(union myunion) \
(short [4]) {9, 10, 11, 12}};
/** ??? **/

int main(void)
{
return 0;
}

/**********************/

Can the above code be made to work, without using runtime
initialization??

Thanks -anon.asdf
 
A

anon.asdf

Code attempt (with compilation errors):
/**********************/

#include <stdio.h>

union myunion {
short arr2[4];
int arr4[2];

};

short arr2_v[4] = \
{1, 2, 3, 4};

union myunion mu_v1 = \
(union myunion) arr2_v;
/** ??? **/

union myunion mu_v2 = \
(union myunion) \
(short [4]) {5, 6, 7, 8};
/** ??? **/

union myunion mu_arr_v3[1] = \
{(union myunion) \
(short [4]) {9, 10, 11, 12}};
/** ??? **/

int main(void)
{
return 0;

}

/**********************/


I've managed to get 2 of the 3 initializations to work:

/**********************/
#include <stdio.h>

union simpleunion {
int a;
short b[2];
};

union myunion {
short arr2[4];
int arr4[2];
};

union simpleunion su_v1 = \
(union simpleunion) (int) 34;

short arr2_v[4] = \
{1, 2, 3, 4};

union myunion mu_v1 = \
{.arr2 = arr2_v};
/** ??? **/

union myunion mu_v2 = \
{.arr2 = \
(short [4]) {5, 6, 7, 8}};


union myunion mu_arr_v3[1] = \
{{.arr2 = \
(short [4]) {9, 10, 11, 12}}};

int main(void)
{
return 0;
}
/**********************/


Is there a way of doing:
/****/
short arr2_v[4] = \
{1, 2, 3, 4};

union myunion mu_v1 = \
{.arr2 = arr2_v};
/****/

without resorting to:
/****/
#define ARR {1, 2, 3, 4}

short arr2_v[4] = \
ARR;

union myunion mu_v1 = \
{.arr2 = (short [4]) ARR};
/****/

-anon.asdf
 
J

Jens Thoms Toerring

Code attempt (with compilation errors):
/**********************/

#include <stdio.h>

union myunion {
short arr2[4];
int arr4[2];

};

short arr2_v[4] = \
{1, 2, 3, 4};

union myunion mu_v1 = \
(union myunion) arr2_v;

No, this won't work, since arr2_v is used in value context, so
it's converted to a pointer to it's first element. And you can't
cast that to a union type. Moreover, the initializers must be
constants, not something that can only be calculated at run-time,
so even

union myunion mu_v1 = { { arr2_v[ 0 ], arr2_v[ 1 ],
arr2_v[ 2 ], arr2_v[ 3 ] } };

wouldn't work.
union myunion mu_v2 = \
(union myunion) \
(short [4]) {5, 6, 7, 8};

This could be done by

union myunion mu_v2 = { { 5, 6, 7, 8 } };

because according to the C standard

A brace-enclosed initializer for a union object initializes the
member that appears first in the declaration list of the union
type.

Initializing the second member (i.e. arr4) don't work in C89
while in C99 you could do

union myunion mu_v2 = { .arr4 = { 5, 6, 7, 8 } };

to initialize the second member insteadof the first.
union myunion mu_arr_v3[1] = \
{(union myunion) \
(short [4]) {9, 10, 11, 12}};

Not possible in C89 but in C99, see above.
I've managed to get 2 of the 3 initializations to work:
/**********************/
#include <stdio.h>
union simpleunion {
int a;
short b[2];
};
union myunion {
short arr2[4];
int arr4[2];
};
union simpleunion su_v1 = \
(union simpleunion) (int) 34;

To initialize the 'a' member you need

union simpleunion su_v1 = { 34 };

You're definitely too triger-happy with casts, avoid them unless
you know exactly why you need them.
short arr2_v[4] = \
{1, 2, 3, 4};
union myunion mu_v1 = \
{.arr2 = arr2_v};

Same as above, you try to assign a pointer to the first element
of the arr2_v array. And again, initializers have to be compile
time constants (or simple expressions that can be evaluated
already at compile time)
union myunion mu_v2 = \
{.arr2 = \
(short [4]) {5, 6, 7, 8}};

Just use

union myunion mu_v2 = { { 5, 6, 7, 8 } };
union myunion mu_arr_v3[1] = \
{{.arr2 = \
(short [4]) {9, 10, 11, 12}}};

And here

union myunion mu_arr_v3[1] = { { { 9, 10, 11, 12 } } };
Is there a way of doing:
/****/
short arr2_v[4] = \
{1, 2, 3, 4};
union myunion mu_v1 = \
{.arr2 = arr2_v};
/****/
without resorting to:
/****/
#define ARR {1, 2, 3, 4}
short arr2_v[4] = \
ARR;
union myunion mu_v1 = \
{.arr2 = (short [4]) ARR};

Again the cast is wrong and you don't need the '.arr2 =' (which
only works for C99 anyway). Use

union myunion mu_v1 = { ARR };

And no, you can't use the elements of arr2_v for the initialization
since they aren't compile time constants. And 'arr2_v' in a place
where the compiler expects a value isn't what you seem to assume
it to be but simply a pointer to the first element of that array.
Enclosing it in curly braces doesn't change anything about that.

Regards, Jens
 
A

anon.asdf

[snip]
union myunion mu_v2 = { { 5, 6, 7, 8 } };
union myunion mu_arr_v3[1] = \
{{.arr2 = \
(short [4]) {9, 10, 11, 12}}};

And here

union myunion mu_arr_v3[1] = { { { 9, 10, 11, 12 } } };
Is there a way of doing:
/****/
short arr2_v[4] = \
{1, 2, 3, 4};
union myunion mu_v1 = \
{.arr2 = arr2_v};
/****/
without resorting to:
/****/
#define ARR {1, 2, 3, 4}
short arr2_v[4] = \
ARR;
union myunion mu_v1 = \
{.arr2 = (short [4]) ARR};

Again the cast is wrong and you don't need the '.arr2 =' (which
only works for C99 anyway). Use

union myunion mu_v1 = { ARR };

And no, you can't use the elements of arr2_v for the initialization
since they aren't compile time constants. And 'arr2_v' in a place
where the compiler expects a value isn't what you seem to assume
it to be but simply a pointer to the first element of that array.
Enclosing it in curly braces doesn't change anything about that.

Hallo Jens! Danke für die sehr gute Erklärung! -Albert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top