SuperC allows function overload with manual symbol mangling.
This is what _Generic does in C11, but made easy.
When a function call is made in SuperC, the compiler will not search the function only by name, it will also search by parameter types; which means that when you have two functions with the same name but different type of parameters, the compiler will call the one that matches (in name, and parameter types).
This means that the collision of the symbols only happen in the linker, so if you have two functions with the same symbol, the linker will throw an error; but the compiler won’t throw an error if they have the same name, but different symbols (and signature of course).
Note: No variadic function can be overloaded
#include <stdio.h>
void foo(float a) __attribute__((symbol("foo_f"))) {
printf("FLOAT: %f\n", a);
}
void foo(int a) __attribute__((symbol("foo_i"))) {
printf("INT: %d\n", a);
}
// Examples of linker errors:
// void foo_f(); // Link error: redefinition of symbol 'foo_f'
// void bar() __attribute__((symbol("foo_f"))); // Link error: redefinition of symbol 'foo_f'
int main(void) {
foo((int) 10);
foo((float) 3.1415);
// INT: 10
// FLOAT: 3.141500
return 0;
}
#include <stdio.h>
#define foo(a) _Generic((a), \
int: foo_i(a), \
float: foo_f(a))
void foo_f(float a) {
printf("FLOAT: %f\n", a);
}
void foo_i(int a) {
printf("INT: %d\n", a);
}
int main(void) {
foo((int) 10);
foo((float) 3.1415);
// INT: 10
// FLOAT: 3.141500
return 0;
}
#include <stdio.h>
/* Methods don't collide by default,
* so no attribute symbol is needed */
int (int a) sum(int b) {
// __func__ will print the symbol
// of the function
printf("1: %s\n", __func__);
return a + b;
}
int (int a) sum(double b) {
// __func__ will print the symbol
// of the function
printf("2: %s\n", __func__);
return a + (int)b;
}
int main(void) {
int x = 10;
printf("=> %d, %d\n", x.sum(x), x.sum(11.1));
// 2: sum$id
// 1: sum$ii
// => 20, 21
return 0;
}
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int sum(int a, int b) {
return add(a, b);
}
int sum(short a, short b) __attribute__((symbol("sum_shorts"))) {
return a - b;
}
int main(void) {
// Function 'sum' has two overloads, so
// specify the parameters in the reference
// to select the overload desired
int (*foo)(int, int) = sum(int, int);
int (*bar)(short, short) = sum(short, short);
printf("foo: %d\n", foo(7, 3));
printf("bar: %d\n", bar(7, 3));
// Function 'add' has no overload, so
// there is no need to specify parameters in the reference
int (*add2)(int, int) = add;
printf("add2: %d\n", add2(7, 3));
// foo: 10
// bar: 4
// add2: 10
return 0;
}