5

Possible Duplicate:
How can I simulate OO-style polymorphism in C?

I'm trying to use unions to create polymorphism in C. I do the following.

typedef struct{
...
...
} A;

typedef struct{
...
... 
} B;

typedef union{
        A a;
        B b;
}C;

My question is: how can I have a method that takes type C, but allows for A and B's also. I want the following to work:

If I define a function:

myMethod(C){
...
}

then, I want this to work:

main(){
A myA;
myMethod(myA);
}

It doesn't. Any suggestions?

Community
  • 1
  • 1
AFS
  • 628
  • 1
  • 6
  • 13

3 Answers3

4

GNU and IBM support the transparent_union extension:

typedef union __attribute__((transparent_union)) {
        A a;
        B b;
} C;

and then you can use As or Bs or Cs transparently:

A foo1;
B foo2;
C foo3;
myMethod(foo1);
myMethod(foo2);
myMethod(foo3);

See The transparent_union type attribute (C only).

hroptatyr
  • 4,702
  • 1
  • 35
  • 38
  • Thanks so much. Followup question: While this worked, it does not work when I create an array: C[5] myArray; C[0]= a; This does not work and needs explicit casting. Is there any way around that? Thanks! – AFS May 23 '12 at 14:50
  • indeed, it's not as transparent as you think, the correct assignment there would be `C[0].a = a;` – hroptatyr May 23 '12 at 15:00
0

You have to use explicit type conversion:

A myA;
myMethod((C) myA);
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • What about __attribute__((transparent_union)) as specified above? –  Feb 06 '19 at 06:31
  • @traducerad Maybe, I haven't read about it. But note that it's a compiler-specific extension and not portable. – Some programmer dude Feb 06 '19 at 06:50
  • Please, feel free to correct me, but I feel like many people give to much importance to compiler portability. In most people's cases I feel like being GCC compliant is more than enough, no need to be compliant to all the exotic compilers out there. Linux is afaik doesn't compile with all the compilers (maybe only gcc?) –  Feb 06 '19 at 06:53
  • @traducerad That's highly project specific. Is one of the goal of the project to be portable? Then don't use non-standard non-portable constructs. Will the program only ever be used on a single compiler and only a narrow version range of that compiler (extensions might change, become deprecated or even removed in newer versions) then go ahead and use whatever extensions you like. I personally tend to go for portable code is possible, even if not working on a portable project. – Some programmer dude Feb 06 '19 at 06:57
0

The short answer is that in C, you can't.

In C++, you could overload myFunction() and provide several implementations.

In C, you can only have a single myFunction(). Even if you could declare the function so that it could take A, B or C (e.g. as void*), it would have no way of knowing which of the three it has been supplied with.

NPE
  • 486,780
  • 108
  • 951
  • 1,012