Tada! Finally a non-Javascript post for those of you who stopped visiting my blog because of my sick Js addiction. So my lost friend Aditya is back, and while talking to him, I got to read a piece of code that he wrote when we were in third semester, last year. The aim was to build a generic container to store different datatypes, in C. So yes, literally storing [21, "abhishek", 3.142, 'z'] in a single dynamically allocated linkedlist. That was pretty bold for us then.

For making that happen, he made use of the _Generic macro that C11 introducted for generic type selection. For those unfamiliar with it, I'll begin with explaining the basics of the macro. For those of you interested in the linkedlist code, scroll down to the bottom of this article. You can always check out the C11 draft [section 6.5.1.1 Generic selection pg #96] (the standard costs around $60 but is essentially the same thing).

The _Generic macro follows the format _Generic(controlling-expression, association-list) where controlling-expression is the expression whose type is to be detected, and association-list is the dictionary of type-expression pairs where type can be any object type and the expression can be any expression, constant or a pointer to any function, pretty much anything that can be evaluated.

To put it simply, compare it to the switch statement for type detection. For example,

#include <stdio.h>
int main() {
  char *teststring = "my char array"; // target object
  char *type = _Generic(
    teststring,
    int: "int",
    int*: "int *",
    char: "char",
    char*: "char *",
    float: "float",
    default: "default"
  );
  printf("%s", type);
  return 0;
}

~$ gcc main.c
~$ ./a.out
char *

The _Generic macro can be wrapped around in a nice looking function call, say detect_type(). Compare this to a (pseudo) switch statement which evaluates the case that matches the switch params

// Pseudocode may resemble Javascript. Reader discretion advised
var someobj = "text here"; // target object
var type; // to store the typename
type_switch(someobj) {
  case int:
    type = "int";
  case int*:
    type = "int*";
  case char:
    type = "char";
  case char*:
    type = "char*";
  default:
    type = "default";
}
print(type)

So that is it. A compile time type identification in C with a simple macro. We can do pretty amazing stuff with it using pointers to functions. For example, a generic print function, that can take in any type of argument and print it. I have added cases for integers, characters and string, but others can be added just as easily.

That was neat, wasn't it. Now back to Aditya. He used the same macro to create a dynamically allocated linkedlist. I am pasting the gist here so that you can read his beautiful code.

File linkedlist.c

File linkedlist.h

File main.c

To compile it, run

~$ gcc main.c linkedlist.c -o linkedlist
on any machine with GCC installed (I've tested it on version >4.9). Run it with
~$ ./linkedlist
and you should see the different elements that we've added printed on the standard out. You may also pack the linkedlist into a statically linked library, by running.

~$ gcc -c linkedlist.c -o linkedlist.o
~$ ar rcs linkedlist.a linkedlist.o
~$ gcc main.c linkedlist.a

Interesting, isn't it? Want to thank him, or have any comments or improvements? Drop them into the comment box. Thank you for reading.

External Links



Unrelated