This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Circular Typedefs

Structs can easily have circular references:

struct ATag { struct BTag* pB; };
struct BTag { struct ATag* pA; };

Can the same thing be done with typedefs?
typedef struct { BType* pB; } AType; //???
typedef struct { AType* pA; } BType;

  • Jon,

    Since this is strictly a C question I took it to news:comp.lang.c and here is Chris Torek's response (I hope you don't mind):

    >Structs can easily have circular references:
    >
    >struct ATag { struct BTag* pB; };
    >struct BTag { struct ATag* pA; };
    >
    >Can the same thing be done with typedefs?
    
    No.
    
    As you are no doubt aware, I consider the typedef keyword nearly
    (though not *quite* completely :-) ) useless.  It does not define
    a new type; it merely creates an alias for an existing type.  It
    is the struct keyword (with the subsequent syntactic bits) that
    defines the new type, and the tag is the "proper name" for that
    structure.  If there is no tag -- if it is an unnamed structure
    type -- then a typedef around it can "capture" the type and assign
    it an alias.  In this case, you get an unnamed structure with some
    alias(es).
    
    If one is enamored of typedefs, however, one can achieve the
    desired goal:
    
    >typedef struct { BType* pB; } AType; //???
    >typedef struct { AType* pA; } BType; /* End other's question */
    
    The trick is that you must give all the structures a proper name
    (a tag) and -- this looks weird but is crucial -- you must write
    the typedefs *first* (optionally with an incomplete declaration
    of the tag):
    
        typedef struct ATag AType;
          /* "struct ATag" is the true name; AType is the alias */
    
        typedef struct BTag BType; /* likewise */
    
    Now you may use the typedefs "circularly", because they have all
    been "declared forward", to borrow the Pascal terminology:
    
        struct ATag { BType *pB; };
        struct BTag { AType *pA; };
    
    <opinion> The true names, "struct ATag" and "struct BTag", are of course
    much more reasonable to use than the typedef aliases.  :-) </opinion> 
    

    - Mark