Search code examples
cpointersstructinitializationforward-reference

C forward-referencing structures - 1) must be with a pointer? 2) must be initialized?


I'm trying to forward reference a (nested) structure, in C.

That means I have a structure and in it I'm referencing to another structure that is declared later.

If I declare the nested structure as a pointer, and initialize it with values, it works.

The following code works:

#include <stdio.h>

struct computer{
    double cost;
    int year;
    char cpu_type[16];
    struct cpu_speed *sp; //this is the question (1)
};

struct cpu_speed{
    int num;
    char type[16];
};

typedef struct computer SC;
typedef struct cpu_speed SS;

void DataR(SC *s);
void DataP(SC *s);

int main(){
   // this is question (2)
    SS speed = {4,"giga"};    
    SC model[2] = {
    { 0,1990, "intel", &speed},
    { 0,1990, "intel", &speed}
    };

    int i;
    for(i=0;i<2;i++) {
        printf("computer no. %d \n", i+1);
        DataR(&model[i]);
    }
    printf("here's what you entered: \n");
    for(i=0;i<2;i++) {
        printf("computer no. %d \n", i+1);
        DataP(&model[i]);
    }
    return 0;
}

void DataR(SC *s){
    printf("the cost of your computer: ");
    scanf("%lf", &s->cost);
    printf("the year of your computer: ");
    scanf("%d", &s->year);
    printf("the type of cpu inside your computer: ");
    scanf("%s", s->cpu_type);
    printf("the speed of the cpu: ");
    scanf("%d %s", &(s->sp->num), s->sp->type);

}

void DataP(SC *s){

    printf("the cost: %.2lf\n",s->cost); 
    printf("the year: %d\n",s->year); 
    printf("the cpu type: %s\n",s->cpu_type); 
    printf("the cpu speed: %d %s\n",s->sp->num, s->sp->type);
}

If I declare the nested struct (i.e. struct cpu_speed{...};) before the parent(?) struct, I do not need to use a pointer, and I also don't need to initialize.

Meaning:

(1) I can use struct cpu_speed speed; instead of struct cpu_speed *sp;. (2) I do not need to give initialized values to the structures variables.

My questions again - in forward referencing structure - (1) do you have to declare it with a pointer? and (2) do you have to initialize the values?


Solution

  • Structures are only used by the compiler to align your memory. Thus, it needs to know the size of struct members.

    struct foo {
        struct bar *pointer;
    };
    

    In this case, the sizeof(pointer) is unrelated to the bar struct and thus the compiler does not need to know anything more.

    However, if you want to add the bar struct to the foo struct, it does need to know about its individual members.

    struct bar {
        const char *string;
        uint64_t integer;
    };
    
    struct foo {
        struct bar sub;
    };
    

    You need to declare the bar struct before foo because the compiler needs to know what you're referring to. Otherwise, how would it know what to do with this (illegal) code:

    struct bar {
        struct foo sub;
    };
    
    struct foo {
        struct bar sub;
    };