• Status: Solved
• Priority: Medium
• Security: Public
• Views: 1715

# Initialize a union?

I am building a small library to do some 4d math for graphics/physics simulation. It is designed to be optimized for the altivec SIMD platform (mostly mac G4/G5).

I am trying to build a simple data type that I can use for both vector and non-vector operations, as my library evolves.

The altivec stuff is not important for this question. There is a base type called "vector float" that is a 128 bit variable, that represents 4 floats.

The defenition of my union (for a 4x4 matrix is):

typedef union {
struct {
vector float c0, c1, c2, c3;
};
float c[4][4];
float e[16];
} AVMatrix4;

Is there any way to initialize this union with 4 vector floats.

I try:

vector float vf = {1.0f, 1.0f, 1.0f, 1.0f};
AVVector4 v = {{vf, vf, vf, vf}};

and gcc gives me "warning: aggregate has a partly bracketed initializer"
0
jukes1
2 Solutions

Commented:
You can initialize the *first* member of the union
AVMatrix4 v = {{1.0f, 1.0f, 1.0f, 1.0f}};

(see http://www.eskimo.com/~scs/C-faq/q2.20.html)
0

Commented:
jukes1,

To add to what Mercantilum has posted, you can also do:

vector float vf = {1.0f, 1.0f, 1.0f, 1.0f};
AVMatrix4 v = {{vf, vf, vf, vf}};

*Note: Your union is not AVVector4 but AVMatrix4.
>> AVVector4 v = {{vf, vf, vf, vf}};

b.
0

Commented:
>gcc gives me "warning: aggregate has a partly bracketed initializer"

this works fine for me ... gcc 2.96

#include <stdio.h>

typedef struct
{
float a,b,c,d;
}vector_float;

typedef union {
struct {
vector_float c0, c1, c2, c3;
};
float c[4][4];
float e[16];
} AVMatrix4;

int main ()
{
vector_float vf = {1.0f, 1.0f, 1.0f, 1.0f};
AVMatrix4 v = {{vf, vf, vf, vf}};
}

I think the problem is "Note: Your union is not AVVector4 but AVMatrix4." as booki noted or may be you tracked the warning down to wrong data type
0

Author Commented:
booki,

You're right, its a AVMatrix4.

Sunnycoder, your code fails to compile with gcc 3.3 and my default compiler flags.

It gets a little more specific though. It still throws the aggregate warning, but it also gives me the error:

"error: cannot convert `vector_float' to `float' in initialization"

I figured out what the problem is. I am trying to initialize the structure in a C++ implementation file. When used in a C file, there are no errors or warnings.

I do not do a whole lot of mixing the languages. Can someone explain how to include and initialize the "C-style" structure in a .cpp file?
0

Commented:
jukes1,

Problem:

C++ does not allow for anonymous structures (no tag and no object or typedef name).  Some compilers however allow it (but only as a member of a union) as an extension to the C++ language.  The standard states that "the brace shall only contain an initializer for the first member of the union."  g++, with its extension (allowing anonymous structs in unions), implements this as the "first named member".  That is, with g++, the initializer of a union initializes the first named member.

In AVMatrix4, the first named member is a 2-D, 4x4 array of floats 'c'.  The statement:

>>  AVMatrix4 v = {{vf, vf, vf, vf}};

therfore attempts to initialize the first row (c[0][0] ~ c[0][3]) of floats with vector_floats. Hence the error.

Solution:

Name the member.  This should compile in C++.

#include <stdio.h>

typedef struct
{
float a,b,c,d;
}vector_float;

typedef union {
struct {
vector_float c0, c1, c2, c3;
} a;
float c[4][4];
float e[16];
} AVMatrix4;

int main ()
{
vector_float vf = {1.0f, 1.0f, 1.0f, 1.0f};
AVMatrix4 v = {{vf, vf, vf, vf}};
}

b.
0

Author Commented:
Ok, that clears up a lot. I kept reading about the gcc unnamed union/structure extension, but missed the fact that initializing a union only initializes the first NAMED member, and not the first UNNAMED member.

Unfortunately, naming the member makes the union too annoying to use. Really the only reason I was trying to figure this out is because I am trying to design these couple of math classes to be optomized on my mac, and the easiest UI language to write in is objective-C.

I would prefer to just use c++ classes for this stuff, but you can't store a c++ class directly in an Objective-C structure, you can only store a pointer, and I don't like the syntax that this causes, and construction/destruction is a bit strange.

Thanks for all of the help people.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.