6

I'm having an issue trying to nest structs that I need to declare as new var types. The code is the following-

typedef struct
{
    typedef struct
    {
        int day,
            month,
            year;
    } Date;

    Date manuDate,
         purDate;
    double purPrice;
} Car;

Except when I try to compile it throws an error at me saying

"Syntax error before typedef" and a bunch of other errors due to that further down.

Is this something C cannot do? I know it has issues with nested structs without having a pointer but I'm not sure how that would work in this case...

kdopen
  • 8,032
  • 7
  • 44
  • 52
James McGrath
  • 187
  • 1
  • 4
  • 15

4 Answers4

7

C does not support nested structure definitions. Perhaps you were looking at some C++ code.

Instead, you simply define the "inner" struct first, and then reference it within the "outer" struct.

typedef struct
{
    int day,
        month,
        year;
} Date;


typedef struct
{
    Date manuDate,
         purDate;
    double purPrice;
} Car;
kdopen
  • 8,032
  • 7
  • 44
  • 52
7

C does have nested structs/unions/enums but not nested typedefs.

struct A { typedef struct B { int x; } B; }; //WRONG
struct A { struct { int x; } b; }; //OK - an anonymous nested struct w/ an instance
struct A { struct { int x; }; }; //OK - an anonymous nested struct w/out an instance; x effectively belongs to `struct A`
struct A { struct B { int x; } b; }; //OK, the `struct B` type also becomes available in the outer scope
struct A { struct B { int x; }; }; //WRONG, a tagged nested struct needs at least 1 instance

The nested structs/unions/enums can either be anonymous (untagged) in which case they become part of the outer struct/union or tagged.

An anonymous inner struct/union can also get away without defining instances, in which case the inner members become members of the outer struct/union recursively.

A tagged nested struct/union/enum needs instances and it's like an anonymous nested struct/union/enum with instances except the tagged type also becomes available for later use, behaving as if it were a standalone outer-scope struct/union/enum definition.

It might be wise to simply put a tagged struct/union/enum in the outer scope rather than confusingly nest it inside another struct/union.

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • Well, taking the case `struct A { struct B { int x; } b; };` in C++ one could do `typedef struct A::B bar_t;`, and in C it would be `typedef struct B bar_t;`, making possible to use typedef with a nested struct, but since they differ I would not recommend doing this. – Wellington Sep 15 '22 at 18:37
  • 1
    @Wellington What's important to understand is that in C, unlike C++, `struct A { struct B { int x; } b; };` does not create any `struct A::B` type. What you get is `struct A` and `struct B`. In C, `struct A { struct B { int x; } b; };` is just a slightly confusing way of writing `struct B { int x; }; struct A { struct B b; };` but both `A` and `B` go to the same `tag` namespace (which has no nesting (no `::`) and is, again somewhat confusingly` shared with `enum` tags and `union` tags but not regular identifiers) at the appropriate block nesting level. – Petr Skocik Sep 15 '22 at 18:52
-2

It does not work, because that is strictly a OOP feature. C is not OO. If you remove the 'typedef' from the inner struct and replace its use in the 'inner' declaration with a 'void*', it will compile. Therefore, if you are looking to do crazy OOP style nestings, you will have to utilize your 'void*' - there is no other way to do it in C.

If you really want to do nested stuff, you will have to remove the typedef. What you could do is use unnamed structs to create structured variables within your main struct.

Example:

typedef struct ObjectType {
    float width;
    float height;
    float x;
    float y;

    //Nested Struct
    struct {
        float r;
        float g;
        float b;
        float a;
    } color; //color is a variable

} Object;
AndreGraveler
  • 437
  • 6
  • 12
-2

C does support nested structures except that you can not use the nested structure externally for reference.

typedef struct
{
    typedef struct Date
    {
        int day,
            month,
            year;
    } manuDate, purDate;

    double purPrice;
} Car;


Car car;

car.manuDate.year = 2020;
car.manuDate.month = 1;
car.manuDate.day = 1;
car.purDate.year = 2020;
car.purDate.month = 2;
car.purDate.day = 14;


car.purPrice = 15000.00;

I just tried that on a C compiler from the year 1996 (VisualAge C) and it works well.