How to do polymorphism in C ?
from Titas Dey
Well the title is a clickbait,but it’s true in a limited sense.
If you've written some C code you've probably used most of the features in C like structure,functions,pointers,arrays and perhaps even the preprocessor.
However, I will talk about one of the lesser used features in C – union
The Union
A union allocates a single shared block of memory, large enough to hold its largest member (with some padding, depending on alignment).
Unlike a struct, which allocates distinct memory for each member, a union allows multiple members to occupy the same memory space.
For example:
#include<stdio.h>
#include<string.h>
struct xyz {
int x;
float y;
char z[10];
};
union tuv {
int t;
float u;
char v[10];
};
int main(void) {
struct xyz st_eg;
union tuv un_eg;
printf("%d\n", sizeof(st_eg)); // O/P: 20 bytes (4 + 4 + 10 + 2 bytes padding)
printf("%d\n", sizeof(un_eg)); // O/P: 12 bytes (10 bytes for v + 2 bytes padding)
strcpy(&un_eg.v, "HelloWorld");
printf("%s\n", un_eg.v); // O/P: HelloWorld
printf("%f\n", un_eg.u); // O/P: 1143139122437582505939828736.000000
return 0;
}
Here, both the integer, float, and character array occupy the same memory region.
When "HelloWorld" is copied into the character array v, reading that memory as a float outputs the string "HelloWorld" typecasted into float
a short essay on union.
- But why do we need union ?
- Why to allocate memory for only the largest member and not all of them using struct ?
A union is valuable when you want different interpretations of the same memory.
Example 1: Storing an IPv4 Address
#include<stdio.h>
typedef union {
unsigned int ip_add;
unsigned char bytes[4];
} ipv4_add;
int main(void) {
ipv4_add my_address = {0};
my_address.bytes[0] = 127;
my_address.bytes[1] = 55;
my_address.bytes[2] = 115;
my_address.bytes[3] = 0;
printf("%x\n", my_address.ip_add); // O/P: 73377f
return 0;
}
Explanation
Using a union, we can store both the integer representation and the byte-wise representation of an IPv4 address within the same space. This approach eliminates the need for explicit bit-shifting or manual conversions.
Example 2: Unions in Embedded Programming
Unions are widely used in embedded systems to represent hardware registers that can be accessed both as a whole and as individual fields.
#include<stdio.h>
union HWRegister {
struct { // annonymous structure
unsigned char parity;
unsigned char control;
unsigned char stopbits;
unsigned char direction;
};
unsigned int reg;
};
int main(void) {
union HWRegister gpioa;
gpioa.reg = 0x14424423;
printf("%x\n", gpioa.stopbits); // O/P: 14
return 0;
}
In this example, the same memory can be accessed as a single 32-bit register or through specific bit fields. This design improves clarity while maintaining memory efficiency — a common requirement in low-level programming.
Example 3: A Glimpse of Polymorphism in C
Now coming back to the title , we can do something similar to OOP in C:
#include<stdio.h>
typedef enum {
JSON_STR,
JSON_BYTE,
JSON_INT,
} json_type_t;
#define JSON_MAX_STR 64
typedef struct {
json_type_t type;
union {
char str[JSON_MAX_STR];
char byte;
int number;
};
} json_t;
void printJSON(json_t *json) {
switch (json->type) {
case JSON_STR:
printf("%s\n", json->str);
break;
case JSON_BYTE:
printf("%c\n", json->byte);
break;
case JSON_INT:
printf("%d\n", json->number);
break;
}
}
int main(void) {
json_t myJSON;
myJSON.type = JSON_INT;
myJSON.number = 97;
printJSON(&myJSON);
return 0;
}
Here, the structure json_t can hold one of several possible data types — a string, a single byte, or an integer.
The active type is determined at runtime using the type field.
There are some issues in this , in C the types are not tightly enforced by the compiler , so if we do
myJSON.type = JSON_STR;// // instead of JSON_INT
myJSON.number = 97;
printJSON(&myJSON); // O/P: a
- The output will be : a (the ascii charector of value 97)
And that's all.
print("Titas , signing out ")
Updated JSON


How to check
Again, we will use id() to see the ids of the objects.
One last question: What if we create two integer objects with the same value?