Wednesday, May 14, 2008

Function overloading In C

Background:
=========

A few days back, me and my friend were discussing if it would be possible to implement function overloading in C. We discussed a few approaches but none seemed to provide a complete solution. So as you would expect from a developer, as soon as I came back home, I started working on it. Consequently after 2 days worth of work I came up with coverload.h . Just include this file in your code and start overloading in C :)
#include "coverload.h"

By using the macros defined in this file you can imitate function overloading. I would not say that its a 100% solution, but very close.

Basic Idea:
========

As in C++, we rely on name decoration (or name mangling) to mangle the names of functions. For example:

void foo(int x,float y) will be name mangled to something like void fooint_float(int x,float y)

Function Declaration:
===============

All functions should be declared using the DECL_FUNC macro:

DECL_FUNC(function_name, return_type, parameters)

Where:

function_name: name of the function
return_type: is the return type of the function (DAH!!!)
parameters: A comma seperated list of parameters. Each parameter is specified via the PARAM(type,name) macro

For Example:
Here is how you can declare a function named foo, having return type int and taking double and long parameters:

DECL_FUNC(foo,int,PARAM(double,dparam),PARAM(long,lparam))
{
.....
}

And this is how you will overload the above function:

DECL_FUNC(foo,int,PARAM(int,iparam))
{
......
}


Function Invocation:
===============


To invoke a function, the INVOKE_FUNC macro should be used:

INVOKE_FUNC(FUNCNAME_FROM_TYPES(func_name,arg_types),arg1,arg2,arg3,...)

Where:

func_name: name of the function
arg_types: a command seperated list of arg types
arg1,arg2... : a comma seperated list of arg values



Note that we need to invoke the FUNCNAME_FROM_TYPES arguments to construct the name of the
actual function to invoke.

For Example:
In order to invoke a function named foo having a double and long parameter do the following:

INVOKE_FUNC(FUNCNAME_FROM_TYPES(foo,double,long),4.5,20L)


Below we invoke the overloaded version of foo, that takes one int parameter:

INVOKE_FUNC(FUNCNAME_FROM_TYPES(foo,int),4)


Limitations:
========
  • I have'nt done any real testing for now (will do it at my earliest and publish the bug fixes)
  • Right now this can only work with 5 function parameters. However as you can see from the macro definitions, adding support for more parameters is very easy (mere copy paste) now. Also I am currently working on a script that will auto-generate the coverload.h file. It will be published as soon as it gets completed.
  • I have'nt tested the code with pointers. So for now you cannot use pointers with "*". However if you really want to use pointers, there is a workaround; If you typedef your pointers , you should be fine.
Examples:

You can find some usage examples in overload.c

2 comments:

Babar said...

Cool!!!

Wajid said...

Hi Sibtey,
Nice poem u wrote that i got through email..About this article you have written, frankly it is all Greek to me..the fault all being mine obviously..Anyway, take care and keep writing..
Wajid