By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,346 Members | 2,158 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,346 IT Pros & Developers. It's quick & easy.

Union Initialization

P: n/a
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

Jun 20 '07 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Theo R. wrote:
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!

--
Eric Sosman
es*****@acm-dot-org.invalid

Jun 20 '07 #2

P: n/a
On Jun 20, 7:25 am, Eric Sosman <esos...@acm-dot-org.invalidwrote:
Theo R. wrote:
Hi all,
Is this legal? gcc throws a bunch of warnings for the initialization.
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

Jun 20 '07 #3

P: n/a
Theo R. said:
On Jun 20, 7:25 am, Eric Sosman <esos...@acm-dot-org.invalidwrote:
>Theo R. wrote:
Hi all,
Is this legal? gcc throws a bunch of warnings for the
initialization.
> 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')
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".

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jun 20 '07 #4

P: n/a

"Theo R." <sh*************@gmail.comha scritto nel messaggio news:11**********************@w5g2000hsg.googlegro ups.com...
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...
Jun 20 '07 #5

This discussion thread is closed

Replies have been disabled for this discussion.