The _Generic keyword in C is used to execute different code based on the data type of an argument. It helps write type-safe, generic code without manually creating separate logic for each data type.
- It can be combined with C macros to imitate function overloading and perform type-specific operations.
- _Generic was introduced in the C11 standard and allows the same code to work with different data types.
#include <stdio.h>
int main(void)
{
// _Generic keyword acts as a switch that chooses
// operation based on data type of argument.
printf("%d\n", _Generic(1.0L, float : 1, double : 2,
long double : 3, default : 0));
printf("%d\n", _Generic(1L, float : 1, double : 2,
long double : 3, default : 0));
printf("%d\n", _Generic(1.0L, float : 1, double : 2,
long double : 3));
return 0;
}
Output
3 0 3
Syntax
_Generic( (expression),
type_1: statements,
type_2: statements,
.
.
default: statements
)
where,
- expression: This test expression's value type is used to determine which statements to execute.
- type_1, type_2...: Types for which we have defined the generic code.
- default: Expression used if no matching type is found
The expression is evaluated, and the matching case based on its type is returned. If no type matches, the default value is returned, if provided.
_Generic in Macros
The _Generic keyword can be used with C macros to perform type-specific operations while providing compile-time type selection.
- A major drawback of C macros is that their arguments do not undergo type checking and can work with different data types such as char, int, and double.
- _Generic allows macros to select the appropriate statement or function based on the argument's type, making them more type-safe.
#include <stdio.h>
// Defining the macro with generic code for
//different argument types
#define geeks(T) _Generic((T), \
char* : "String", \
int : "Integer", \
long : "Long Integer", \
default : "Others")
int main(void)
{
// Here A is a string.
printf("%s\n", geeks("A"));
// floating point value
printf("%s\n", geeks(5));
// float type which is not defined in the macro
printf("%s", geeks(5.12));
return 0;
}
Output
String Integer Others
As we can see, different expressions are returned for different datatypes. This behaviour is similar to C++ function overloading where the parameter types specify which version of the function will be executed. So, we can use the _Generic in C to provide some features of function overloading in our program.
Advantages
_Generic provides compile-time type selection, making C code more flexible and reusable.
- It can be used with macros to simulate function overloading.
- It allows different code to be executed based on the type of the parameter.
- It improves type safety by selecting the appropriate operation for different data types.
Disadvantages
_Generic can make C code more complex, especially when used with macros and multiple data types.
- Its complex syntax can make the code difficult to read and understand.
- Errors can be difficult to debug because
_Genericis often used inside macros. - It can make the expanded code harder to inspect and maintain.