Thread: What is a structure tag?

  1. #1
    Registered User
    Join Date
    Jul 2014
    Location
    Central Arizona
    Posts
    61

    What is a structure tag?

    I've read in the (C++ Quick Guide) that the syntax for a structure has an optional structure tag. What is a structure tag and what info might go into this tag. Can someone give me an example using a tag.


    Jumping into C++ says the tag is the name, I'm confused.

  2. #2
    Registered User
    Join Date
    Jun 2011
    Posts
    4,509
    The tag is simply the name of the struct.

    Structures in C and C++ - Tutorial - Cprogramming.com

    The first two code examples in that link should answer your question. Let us know if it's not clear to you.

  3. #3
    Registered User
    Join Date
    Jul 2014
    Location
    Central Arizona
    Posts
    61
    Thanks Matticus, I've reads that the name is the tag in Jumping into C++ also. The tutorial you pointed out above seem to just be a copy of this book. I've read in the C++ Quick Guide this...
    Code:
     
    struct [structure tag]
    {   
    member definition;
    member definition;
    member definition;
    } 
    [one or more structure variables];
    "They say that the tag is optional" ...If this is true...Than a structure does not always need a name...That's why I'm Confused...Which is right???

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    27,085
    Yes, you could have an unnamed structure. This is very rare in C++, though in C it might be done for a structure that is given a name with typedef instead (in C++ there is no motivation for such a typedef since the tag name can be used as the type name, e.g., for a struct X would could refer to it as X rather than struct X).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    The idea is that a structure definition can either a) declare a new type of structure, or b) declare instance variables of a structure, or c) both. If you only want to use the structure once, you don't need to give it a name (tag).

    In addition to the example laserlight gave, in C you might see a structure without a tag in the case of nested structures... for example,
    Code:
    struct widget {
        int x, y;
        struct {
            void *(*clone)(struct widget *);  // function pointers to clone the widget
            void (*free)(struct widget *);  // and free the widget
        } func;
    };
    
    widget w;
    w.func.free = &free_widget;
    The inner structure separates its members from the outer structure without creating a structure that you can refer to by name. This is more common with unions than structures. (There are also anonymous unions that have neither a name nor instances, but that's a very special case.)
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #6
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Quote Originally Posted by dwks View Post
    ...

    The inner structure separates its members from the outer structure without creating a structure that you can refer to by name. This is more common with unions than structures. (There are also anonymous unions that have neither a name nor instances, but that's a very special case.)
    Yeah and it's boss for representing coordinates!

    Code:
    struct point
    {
        // Use a union as hybrid storage
    
    
        union
        {
            struct
            {
                float x, y, z;
            };
    
    
            float p[3];
        };
    
    
        point(float a, float b, float c) : x(a), y(b), z(c) { };
    
    
        void print(void) const
        {
            printf("(%.00f, %.00f, %.00f)\n", x, y, z);
        };
    };

  7. #7
    Registered User
    Join Date
    May 2009
    Posts
    3,658
    Quote Originally Posted by MutantJohn View Post
    Yeah and it's boss for representing coordinates!

    Code:
    struct point
    {
        // Use a union as hybrid storage
    
    
        union
        {
            struct
            {
                float x, y, z;
            };
    
    
            float p[3];
        };
    
    
        point(float a, float b, float c) : x(a), y(b), z(c) { };
    
    
        void print(void) const
        {
            printf("(%.00f, %.00f, %.00f)\n", x, y, z);
        };
    };
    Is this safe according to the standard?
    Note: I would guess packing might need to be done exactly right or disabled.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  8. #8
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    I have no idea. I feel like it's been discussed here before but I don't quite remember the resolution.

  9. #9
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by stahta01 View Post
    Is this safe according to the standard?
    Note: I would guess packing might need to be done exactly right or disabled.
    Depends what you mean by safe.

    Your code, as presented, only sets the values of struct members x,y, and z and only ever retrieves values of them. There is no usage of the member p. As such, the behaviour is well specified.

    The behaviour would be undefined if one member of the union is set and another member is used to retrieve (e.g. setting x,y,z but retrieving p[0],p[1], and p[2]).

    That said, a fair few library functions would rely on the layout aligning. But "what implementations do" is not the same as "what standards require".
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  10. #10
    Registered User
    Join Date
    Jul 2014
    Location
    Central Arizona
    Posts
    61
    Thank You all for enlightening me. You've provides some interesting examples of when a struct or union don't need to have a name tag. However, after thinking about it for a while, its probably a good practice to supply a name anyway.

  11. #11
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Quote Originally Posted by grumpy View Post
    Depends what you mean by safe.

    Your code, as presented, only sets the values of struct members x,y, and z and only ever retrieves values of them. There is no usage of the member p. As such, the behaviour is well specified.

    The behaviour would be undefined if one member of the union is set and another member is used to retrieve (e.g. setting x,y,z but retrieving p[0],p[1], and p[2]).

    That said, a fair few library functions would rely on the layout aligning. But "what implementations do" is not the same as "what standards require".
    What do you mean by layout aligning?

    Do you mean it's implementation defined that x, y and z are contiguous and in-order in memory? That some compilers would read the struct x, y and z and store them in any order?

    Also and with regards to the union, does the array force x, y and z to be contiguous? The array must be contiguous by definition so does this force x, y and z into also being that way because the same data is shared for all members of the union.

  12. #12
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by MutantJohn View Post
    What do you mean by layout aligning?
    Look up structure padding.

    Placing a struct and an array in the same union does not force the struct members to align with array elements.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  13. #13
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    Okay, I tried this code :
    Code:
    #include <iostream>
    #include <cassert>
    
    
    struct point
    {
        union
        {
            struct 
            {
                float x, y, z;
            };
    
    
            float p[3];
        };
    
    
        point(float a, float b, float c) 
        { 
            x = a;
            y = b;
            z = c;
    
    
            assert(&x == p + 0);
            assert(&y == p + 1);
            assert(&z == p + 2);
        };
    };
    
    int main(void)
    {
        std::cout << sizeof(point) << std::endl;
    
    
        point test(1, 2, 3);
        std::cout << test.x << ", " << test.y << ", " << test.z << std::endl;
        std::cout << test.p[0] << ", " << test.p[1] << ", " << test.p[2] << std::endl;
    
    
        return 0;
    }
    compiled with :
    Code:
    g++ -std=c++11 -Wall -Wextra -pedantic -O3
    There is an ISO warning about anonymity but yolo.

    However, the code seems to work and will crash should the struct not be aligned. From what I could google about this, I found someone on StackOverflow that said,
    C++ guarantees that elements of an array are laid out contiguously, but only guarantees that the address of an element of a POD struct is greater than the address of all earlier-declared elements (i.e. there is more flexibility in laying out structs).
    In this case, there is no padding because the sizeof(point) is 12. Or rather, g++ does not pad because 12 is a sum of powers of 2 (8 + 4). So because of that and C++'s guarantee, the alignment is held properly... in this case. It's because if &y must be > &x and &z must be > &y and there's only 12 bytes of room we can safely use this to establish that the memory really is laid out in order.

    Also, I think this would change if the array was larger. The union is the size of its largest member and if it was say 4 then the guarantee still holds but y and z may not necessarily have 0 spacing between them. As in, the struct could be laid out as x, y, gap, z or x, gap, y, z. We'd hope for x, y, z, gap but that's not guaranteed.

    Is this right?

    It seems like ensuring the the size of the anonymous structure being the same as the array is key here. And that the structure itself (or in this case, class) is natively aligned and receives no padding from the compiler, for example to 16 bytes or something like that.

  14. #14
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    The behaviour would be undefined if one member of the union is set and another member is used to retrieve.
    O_o

    To be clear, this is correct for the current code. With a bit more work, you can benefit from "common initial sequence" rules allowing you to write defined code with similar utility. The code is uglier, but you get the niceness of referencing an array and aliases for the individual elements of that array. Of course, there is what the standard says and how compiler actually behave. If you want guaranteed conformance when the sizes match, you can actually use a similar technique with named temporaries of the relevant `union' (such `myunion temp = a_myunion_instance;') which generally never appear in the compiled binary thanks to optimizations.

    As for the padding related issues, the standard has clear language about internal padding of variable types and how arrays work via the `sizeof' and simple pointer arithmetic. The language of the standard regarding the internal padding and pointer arithmetic of arrays doesn't directly apply to structures, but the primary reason for padding between elements in structures is alignment, and the alignment rules are considered "common layout" without some sort of mechanism to change the layout. In reality, using different rules for arrays and structures consisting solely of the same type while conforming to all relevant parts of the standard for both cases is not practical. Furthermore, if you are worried about the issue, you can use firewalls--especially `static_assert' in C++11, to verify the relevant sizes.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I will point out that your code is not valid C++, MutantJohn.
    Also, why would you want to bother with code that breaks so easily by simply changing compilers/platforms or even adding or reordering members?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 10
    Last Post: 03-18-2014, 10:43 AM
  2. Replies: 4
    Last Post: 04-25-2010, 10:57 AM
  3. Replies: 1
    Last Post: 04-02-2009, 06:51 AM
  4. Replies: 9
    Last Post: 05-21-2007, 12:10 AM
  5. Replies: 4
    Last Post: 11-22-2006, 12:20 PM