Skip to content

Instantly share code, notes, and snippets.

@barosl
Created July 26, 2015 07:26
Show Gist options
  • Star 114 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save barosl/e0af4a92b2b8cabd05a7 to your computer and use it in GitHub Desktop.
Save barosl/e0af4a92b2b8cabd05a7 to your computer and use it in GitHub Desktop.
Function overloading in C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int addi(int a, int b) {
return a + b;
}
char *adds(char *a, char *b) {
char *res = malloc(strlen(a) + strlen(b) + 1);
strcpy(res, a);
strcat(res, b);
return res;
}
#define add(a, b) _Generic(a, int: addi, char*: adds)(a, b)
int main(void) {
int a = 1, b = 2;
printf("%d\n", add(a, b)); // 3
char *c = "hello ", *d = "world";
printf("%s\n", add(c, d)); // hello world
return 0;
}
@jasiek
Copy link

jasiek commented Jul 26, 2015

I wonder if this'll work on the Arduino.

@dataf3l
Copy link

dataf3l commented Jul 26, 2015

works as advertised on osx.

@Tyler-Hardin
Copy link

@jasiek, if you can find a C11 compiler for Arduino. GCC supports the _Generic portion of C11 since 4.9, so it should work with avr-gcc-4.9 or newer.

@2mac
Copy link

2mac commented Jul 26, 2015

You create a memory leak by not storing a pointer to the concatenated string before printing it, since now you can't free it after you malloc'd it.

@patrickt
Copy link

clang provides __attribute__((overloadable)), which enables a limited version of C++-style name-mangling based polymorphism, so that you don't have to write a _Generic wrapper for each function.

@lpereira
Copy link

Here's another example I wrote the other day, that's actually useful: number parsing, regardless of its type: parse_number().

@KLuka
Copy link

KLuka commented Jul 26, 2015

@2mac memory is freed at line 25 😄

OT: thanks for the interesting stuff...

@daurnimator
Copy link

Without C11:

#define NARG_(_15, _14, _13, _12, _11, _10, _9, _8, _7, _6, _5, _4, _3, _2, _1, N, ...) N
#define NARG(...) NARG_(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define PASTE(a, b) a ## b
#define XPASTE(a, b) PASTE(a, b)

int foo(int a, int b) {
    return 1;
}
#define foo2(a,b) foo((a), (b))
#define foo1(x) foo2(x,0)
#define foo(...) XPASTE(foo, NARG(__VA_ARGS__))(__VA_ARGS__)

@theonewolf
Copy link

Is there a way to do stricter type checking on more than one argument? As I read this, it is only checking the type of the first argument?

@dubslow
Copy link

dubslow commented Jul 26, 2015

  1. Type checking only on one argument

  2. main leaks memory

@Benabik
Copy link

Benabik commented Jul 26, 2015

@jasiek: The Arduino IDE uses C++, so function overloading works just fine. (So do templates, but you have to define them in a .h file rather than the default extension-less file.)

@danetrata
Copy link

@KLuka
It's not good practice to not free something you've malloc'd.

@dbvz
Copy link

dbvz commented Jul 26, 2015

Still not supported by Intel C compiler though.

@jaytaylor
Copy link

@Fusion
Copy link

Fusion commented Jul 26, 2015

@dubslow Yes, main leaks memory. I realize now that github has its own "grammar police" since that was not the point of this gist.

@reverofevil
Copy link

@Fusion I'd say it's not github, but C community, as memory leaks is something to avoid even in examples that are this simple.

@spekode
Copy link

spekode commented Jul 26, 2015

DAE notice the memory leak???????????????

@tkellogg
Copy link

OMG did you guys see the memory leak?!!

@Ygrex
Copy link

Ygrex commented Aug 19, 2015

'a' gets evaluated twice

@lrocha3
Copy link

lrocha3 commented Feb 16, 2017

There is a memory leak. You allocate with malloc but you never free the allocated memory. You should fix that.

@etale-cohomology
Copy link

Who says C can't be high-level and beautiful? <3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment