Union Initialization

T

Theo R.

Hi all,

I have the following struct defined -

#define INTEGER 0
#define STRING 1

typedef struct {
char type ;
union {
char buffer[8] ;
int number ;
} ;
} TOKEN ;

I want to create an array of these "TOKEN" structures and initialize
them globally. So I have
static TOKEN t[] = {
{INTEGER, 0} ,
{STRING, 0}
} ;

Is this legal? gcc throws a bunch of warnings for the initialization.

Thanks,
Theo
 
E

Eric Sosman

Theo said:
Hi all,

I have the following struct defined -

#define INTEGER 0
#define STRING 1

typedef struct {
char type ;
union {
char buffer[8] ;
int number ;
} ;
} TOKEN ;

I want to create an array of these "TOKEN" structures and initialize
them globally. So I have
static TOKEN t[] = {
{INTEGER, 0} ,
{STRING, 0}
} ;

Is this legal? gcc throws a bunch of warnings for the initialization.

It is not legal because the struct definition is
illegal. After that, you're in gcc-la-la-land, where
the Standard has nothing to say about what happens.

Try cranking up the compiler's conformance level.
I like "-Wall -W -ansi -pedantic" as a starting point;
some of my code can't tolerate that much strictness,
but I like to make sure I haven't transgressed anywhere
besides where I intended to. ("-ansi" might be replaced
by "-std=something" when compiling to other versions of
the Standard.)

Oh, and one last hint: Next time you have a question
involving some error or warning messages, POST THE MESSAGES,
DAMMIT!
 
T

Theo R.

Oh, and one last hint: Next time you have a question
involving some error or warning messages, POST THE MESSAGES,
DAMMIT!

Oops. Sorry about that! I'm building with -Wall and the warnings I get
are
--
main.c:13: warning: missing braces around initializer
main.c:13: warning: (near initialization for
`t[0].<anonymous>.buffer')
--

Nevertheless, the point is - can we globally initialize unions? Does C
allow that?


Thanks,
Theo
 
R

Richard Heathfield

Theo R. said:
Oops. Sorry about that! I'm building with -Wall and the warnings I get
are

Best to avoid anonymous unions. Define the union type first.

It's also a good idea to separate your typedefs from your type
definitions. This helps to keep things clearer in everyone's heads
about typedef, because typedef DOES NOT define a type, despite its
stupid name. It creates a new synonym for an existing type. The fact
that you /can/ combine it with the creation of a type doesn't mean that
you /should/.

I would suggest something like this:

#define INTEGER 0
#define STRING 1

union bufnum_
{
char buffer[8];
int number;
};

typedef union bufnum_ bufnum;

struct token_
{
char type;
bufnum bn;
};

typedef struct token_ token;
Nevertheless, the point is - can we globally initialize unions? Does C
allow that?

Sure.

static token t[] =
{
{INTEGER, {0}},
{STRING, {0}}
};

Enclose any aggregate type initialisation in its own brace pair, and
you'll be legal. Alas, this may not kill the warning in gcc, but the
compiler is allowed to display any diagnostic messages it likes, and
unfortunately this includes silly messages that actually mean "while
what you are doing is perfectly legal and well-defined, and although
there is absolutely no point in doing it in any other way, it is not
the way I'd have done it, and so I'm going to annoy you by issuing a
really stupid warning message which will mess up your build, without
actually giving you any useful information".
 
A

Army1987

Theo R. said:
Hi all,

I have the following struct defined -

#define INTEGER 0
#define STRING 1

typedef struct {
char type ;
union {
char buffer[8] ;
int number ;
} ;
^
(insert field name here)
} TOKEN ;

I want to create an array of these "TOKEN" structures and initialize
them globally. So I have
static TOKEN t[] = {
{INTEGER, 0} ,
{STRING, 0}
} ;

Is this legal? gcc throws a bunch of warnings for the
initialization.
static TOKEN t = {INTEGER} sets all the members of
t.unnamed_union.char to 0, which, unless sizeof(int) > 8, also sets
t.unnamed_union.int to 0.

In C99 you can use
static TOKEN t[] = {
{INTEGER, {.number = 0} } ,
{STRING, {.buffer = {0}} }
} ;
.. In C89 you can only initialize the first member, AFAIK (but in
this very case, that doesn't matter if sizeof(int) <= 8).

As for your usage (supposing you do give the union a name), C99
says: (6.7.8 p13):

The initializer for a structure or union object that has automatic storage duration shall be
either an initializer list as described below, or a single expression that has compatible
structure or union type. In the latter case, the initial value of the object, including
unnamed members, is that of the expression.
[snip]
Otherwise, the initializer for an object that has aggregate or union type shall be a braceenclosed
list of initializers for the elements or named members.

You're trying to initialize a union with a plain 0...
 

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

Similar Threads


Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top