Union nested in structure.

Discussion in 'C Programming' started by tapeesh@gmail.com, Feb 9, 2005.

  1. Guest

    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..
     
    , Feb 9, 2005
    #1
    1. Advertising

  2. Michael Mair Guest

    wrote:
    > 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
    --
    E-Mail: Mine is a gmx dot de address.
     
    Michael Mair, Feb 9, 2005
    #2
    1. Advertising

  3. Tapeesh Guest

    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?
     
    Tapeesh, Feb 9, 2005
    #3
  4. CBFalconer Guest

    Tapeesh wrote:
    >
    > 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.

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
     
    CBFalconer, Feb 9, 2005
    #4
  5. "Tapeesh" <> writes:
    > 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.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Feb 9, 2005
    #5
  6. In article <>, "Tapeesh" <> writes:

    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?

    --
    Michael Wojcik

    It does basically make you look fat and naked - but you see all this stuff.
    -- Susan Hallowell, TSA Security Lab Director, on "backscatter" scanners
     
    Michael Wojcik, Feb 9, 2005
    #6
  7. >
    > (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
     
    Nathaniel L. Walker, Feb 11, 2005
    #7
  8. "Nathaniel L. Walker" <NatLWalker@no_email.org> writes:
    >> (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.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Feb 11, 2005
    #8
  9. Nathaniel L. Walker wrote:
    >>(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


    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.

    --
    Email: "jonathan [period] burd [commercial-at] gmail [period] com" sans-WSP

    "I usually swear at C++, but so far it has never sworn back."
    - Ben "Noir"
     
    Jonathan Burd, Feb 12, 2005
    #9
  10. Jonathan Burd wrote:
    > Nathaniel L. Walker wrote:
    >


    <snip>

    >
    > /* trouble.c


    Should be statistics.c.

    > Regards,
    > Jonathan.
    >



    --
    Email: "jonathan [period] burd [commercial-at] gmail [period] com" sans-WSP

    "I usually swear at C++, but so far it has never sworn back."
    - Ben "Noir"
     
    Jonathan Burd, Feb 12, 2005
    #10
  11. On 9 Feb 2005 20:36:47 GMT, (Michael Wojcik)
    wrote:
    <snip>
    > 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
     
    Dave Thompson, Feb 14, 2005
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Matt Garman
    Replies:
    1
    Views:
    669
    Matt Garman
    Apr 25, 2004
  2. Jeff Massung

    Setting union member in structure

    Jeff Massung, Dec 22, 2003, in forum: C++
    Replies:
    2
    Views:
    476
    Jeff Massung
    Dec 22, 2003
  3. Peter Dunker

    union in struct without union name

    Peter Dunker, Apr 26, 2004, in forum: C Programming
    Replies:
    2
    Views:
    875
    Chris Torek
    Apr 26, 2004
  4. csudha

    Difference between Structure & Union

    csudha, Sep 10, 2004, in forum: C Programming
    Replies:
    4
    Views:
    1,776
  5. Replies:
    1
    Views:
    211
Loading...

Share This Page