Union nested in structure.

T

tapeesh

I created a C file say struct.c with the following structure
declarations in the same file

struct A
{
union key
{
int i;
float f;
}k1;
};


struct B
{
union key
{
int i;
float f;
}k2;
};


When I compiled this code using
gcc -c struct.c

I got a error

"redefinition of `union key'" at the definition of "union key" in
struct B.


Is it not that the scope "union key" defined in struct A is limited to
struct A? From the behaviour it looks like that nested unions have
global scope.

Can anyone provide me the reason for such behavior?

When i made the file as struct.cpp it compiled without any problem.


Similar is the behaviour if I nest a struct inside a struct..
 
M

Michael Mair

I created a C file say struct.c with the following structure
declarations in the same file

struct A
{
union key
{
int i;
float f;
}k1;
};


struct B
{
union key
{
int i;
float f;
}k2;
};


When I compiled this code using
gcc -c struct.c

I got a error

"redefinition of `union key'" at the definition of "union key" in
struct B.


Is it not that the scope "union key" defined in struct A is limited to
struct A? From the behaviour it looks like that nested unions have
global scope.

Can anyone provide me the reason for such behavior?

When i made the file as struct.cpp it compiled without any problem.

Congratulations: You have just found one of the differences between
the two languages C and C++.
C has _one_ namespace for _all_ structure, union and enumeration tags.
No scope. Effectively, you can write:
struct A
{
union key
{
int i;
float f;
}k1;
};

struct B
{
union key k2;
};
or
union key
{
int i;
float f;
};

struct A
{
union key k1;
};

struct B
{
union key k2;
};


Cheers
Michael

Similar is the behaviour if I nest a struct inside a struct..

Exactly as the language standard demands it.


Cheers
Michael
 
T

Tapeesh

But why does C standard demand such a behaviour? C is very particular
about scope. Why is that scope rules are not followed in case of
structures, unions and enums?
 
C

CBFalconer

Tapeesh said:
But why does C standard demand such a behaviour? C is very particular
about scope. Why is that scope rules are not followed in case of
structures, unions and enums?

Your question makes no sense. What behaviour? In usenet so called
previous articles are often not available at the receivers station,
so each article should stand on its own. That is why we include
attributions and quotations. Even with googles broken beta system
you can do it, see my sig below.
 
K

Keith Thompson

Tapeesh said:
But why does C standard demand such a behaviour? C is very particular
about scope. Why is that scope rules are not followed in case of
structures, unions and enums?

The scope rules are followed. It just happens that the rules are
different for struct, union, and enum tags.

As for why it was originally defined that way, I suppose it was just
easier. This probably goes back at least 30 years. You can certainly
argue that limiting the scope of a tag makes more sense (and
apparently Stroustrup felt strongly enough about it to change the rule
for C++), but the C rules rarely cause problem in practice. (Your
code is one of the rare cases.) It can't be changed now without
potentially breaking existing code.

(BTW, this is a good argument against always compiling your C code
with a C++ compiler; it can cause you to miss this kind of error.)
 
M

Michael Wojcik

I see Chuck Falconer has already posted explaining why you should
(properly) quote text you are replying to, and how to do so correctly
with the braindead Google Groups interface. I won't repeat those
instructions, but I urge you to take them to heart.
But why does C standard demand such a behaviour?

Because that's how the committee thought it should work, and not
specifying the tag scope rules would have been a Bad Thing.

(And, IIRC, the single global-scope tag namespace existed in pre-
standard C as well, so they're preserving existing practice. What
did change was the separation of members into their own scoped
namespace. Or was it that members had their own namespace, but it
had global scope? Or was there only a single namespace for tags,
members, and ordinary identifiers? I no longer have a pre-standard
K&R to consult.)
C is very particular about scope.

With good reason. That does not mean, however, that the scoping
rules are or should be the same for all namespaces.
Why is that scope rules are not followed in case of
structures, unions and enums?

They are. They're just different for the tag namespaces.

The only reason to put a tag on a struct (or union) is to make it a
distinct type. You can leave the tags off structs (or unions) if
they don't need to be treated as distinct types. Often that's the
case when you're defining one struct inside another; otherwise, why
not define the inner one separately, first, to show that it may be
used on its own?
 
N

Nathaniel L. Walker

(BTW, this is a good argument against always compiling your C code
with a C++ compiler; it can cause you to miss this kind of error.)

Well considering 99.9998% of C/C++ compilers will compile aprogram.c
as a 'C' language file, I don't see this problem popping up often, unless
of course they are using command-line parameters (and you'd have a hard
time finding them with gcc [joking]).

Nathaniel L. Walker
 
K

Keith Thompson

Nathaniel L. Walker said:
(BTW, this is a good argument against always compiling your C code
with a C++ compiler; it can cause you to miss this kind of error.)

Well considering 99.9998% of C/C++ compilers will compile aprogram.c
as a 'C' language file, I don't see this problem popping up often,
unless of course they are using command-line parameters (and you'd
have a hard time finding them with gcc [joking]).

This problem pops up all the time here. A lot of people name their C
source files with a ".cpp" suffix. (Note also that some OSs don't
distinguish between "aprogram.c" and "aprogram.C"; I'm not sure how
compilers on those systems behave.)
 
J

Jonathan Burd

Nathaniel said:
Well considering 99.9998% of C/C++ compilers will compile aprogram.c

GNU cc and c++ aren't in that list. See example below.
as a 'C' language file, I don't see this problem popping up often, unless
of course they are using command-line parameters (and you'd have a hard
time finding them with gcc [joking]).

Nathaniel L. Walker

/* trouble.c
(5 green apples + 4 red apples) != 9 red apples.
C != C++.
*/
#include <stdio.h>

enum truth_value {lies, truth};

int
main (void)
{
const enum truth_value statistics = lies;

char *delete = "telling the C++ compiler to throw up.";

if (statistics == lies)
printf ("you know what I mean. :)\n");

puts (delete);

return 0;
}

----
Compiling with a C compiler (one of the most popular ones):

% gcc -pedantic -Wall -std=c89 -o statistics statistics.c
or
% gcc -pedantic -Wall -std=c99 -o statistics statistics.c
% ./statistics
you know what I mean. :)
telling the C++ compiler to throw up.

Compiling with a C++ compiler (one of the most popular ones, again):

% g++ -pedantic -Wall -o statistics statistics.c
statistics.c: In function `int main()':
statistics.c:10: error: expected primary-expression before "char"
statistics.c:10: error: expected `;' before "char"
statistics.c:15: error: expected primary-expression before ')' token

Ooh, my C++ compiler doesn't recognize the .c extension that is so
very clearly present right there.

Bottom line: C != C++. Use a C compiler to compile C code and
use a C++ compiler to compile C++ code. :)

Regards,
Jonathan.
 
D

Dave Thompson

On 9 Feb 2005 20:36:47 GMT, (e-mail address removed) (Michael Wojcik)
wrote:
Because that's how the committee thought it should work, and not
specifying the tag scope rules would have been a Bad Thing.

(And, IIRC, the single global-scope tag namespace existed in pre-
standard C as well, so they're preserving existing practice. What
did change was the separation of members into their own scoped
namespace. Or was it that members had their own namespace, but it
had global scope? Or was there only a single namespace for tags,
members, and ordinary identifiers? I no longer have a pre-standard
K&R to consult.)
*Very* early C had one namespace for (names of) members of all structs
-- or at least all structs at (what we now call) file scope, I don't
recall if there were struct definitions within a function/block at all
-- and you could apply member names "of" (from) any struct as members
of any (other) struct, with often wrong results. This is why the API
structs that survive from early Unix like tm (tm_year, tm_mon etc.)
and <not standard C> stat (st_mode, st_mtime etc.) have the struct
encoded in the member names to ensure they don't conflict. I'm pretty
sure that even then members were isolated from ordinary identifiers
and tags; and that members became per-struct even before K&R1 much
less the standard, though I also no longer have a 1ed to check.

- David.Thompson1 at worldnet.att.net
 

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

No members online now.

Forum statistics

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

Latest Threads

Top