Home > front end >  How do I return one of two types in C?
How do I return one of two types in C?

Time:11-01

Suppose this code

typedef struct A {
    ...
} A;

typedef struct B {
    ...
} B;

// If it was TypeScript I would say `type uknown = A | B;`
uknown getAorB(int k) {
    if (k > 0) return (A){...};
    return (B){...};
}

That function getAorB should return either A or B depending on the parameter k. OK, but what is the return type and is it possible to achieve that in C?

CodePudding user response:

One way to do this would be to have another struct which contains the 'type' of the returned struct. Here is what this may look like:

#define STRUCTA 1
#define STRUCTB 2

typedef struct SUPER {
   int type;
} SUPER;    

typedef struct A {
   int type;
   ...
} A;

typedef struct B {
   int type;
   ...
} B;


SUPER* getAorB(int k) {

    if (k > 0) {
        A *a;
        a = malloc(sizeof(*a));
        a->type = STRUCTA;
        return (SUPER*)a;
    } 
    
    B *b;
    b = malloc(sizeof(*b));
    b->type = STRUCTB;
    return (SUPER*)b;
}

Then in the calling function you check the type of the SUPER and cast it to the appropriate function.

A *a;
B *b;

if (returnedSuper->type == STRUCTA) {
    a = (A*)returnedSuper;
}
else if (returnedSuper->type == STRUCTB) {
    b = (B*)returnedSuper;
}

CodePudding user response:

Use unions.

typedef struct A {
    ...
} A;

typedef struct B {
    ...
} B;

typedef union
{
    struct A a;
    struct B b;
}A_OR_B;

// If it was TypeScript I would say `type uknown = A | B;`
A_OR_B getAorB(int k) {
    A_OR_B c;
    if (k > 0) c.a.member = something;
        else c.b.member = somethingelse;
    return c;
}
  • Related