views:

658

answers:

3
+5  Q: 

Namespaces in C

Is there a way to (ab)use the C preprocessor to emulate namespaces in C?

I'm thinking something along these lines:

#define NAMESPACE name_of_ns
some_function() {
    some_other_function();
}

This would get translated to:

name_of_ns_some_function() {
    name_of_ns_some_other_function();
}
+5  A: 

You could use the ## operator:

#define FUN_NAME(namespace,name) namespace ## name

and declare functions as:

void FUN_NAME(MyNamespace,HelloWorld)()

Looks pretty awkward though.

Mehrdad Afshari
I think #define NS1(name) Namespace1 ## name and then void NS1(some_func)() would look less weird (and actually force you to think your namespaces through)
Vinko Vrsalovic
Yeah, I was thinking of some "context" too. But whatever it is, the idea lies within the ## operator. It's up to the user to adapt it for his/her own needs.
Mehrdad Afshari
Be careful with the concatenation operator is you're using it with other macros. The order of macro-expansion is not strictly defined, and has differed between two compilers that I had to support. Scarily, neither of them was GCC, so I don't even know what it does.
Novelocrat
+9  A: 

Another alternative would be to declare a struct to hold all your functions, and then define your functions statically. Then you'd only have to worry about name conflicts for the global name struct.

// foo.h
#ifndef FOO_H
#define FOO_H
typedef struct { 
  int (* const bar)(int, char *);
  void (* const baz)(void);
} namespace_struct;
extern namespace_struct const foo;
#endif // FOO_H

// foo.c
#include "foo.h"
static int my_bar(int a, char * s) { /* ... */ }
static void my_baz(void) { /* ... */ }
namespace_struct const foo = { my_bar, my_baz }

// main.c
#include <stdio.h>
#include "foo.h"
int main(void) {
  foo.baz();
  printf("%d", foo.bar(3, "hello"));
  return 0;
}

In the above example, my_bar and my_baz can't be called directly from main.c, only through foo.

If you have a bunch of namespaces that declare functions with the same signatures, then you can standardize your namespace struct for that set, and choose which namespace to use at runtime.

// goo.h
#ifndef GOO_H
#define GOO_H
#include "foo.h"
extern namespace_struct const goo;
#endif // GOO_H

// goo.c
#include "goo.h"
static int my_bar(int a, char * s) { /* ... */ }
static void my_baz(void) { /* ... */ }
namespace_struct const goo = { my_bar, my_baz };

// other_main.c
#include <stdio.h>
#include "foo.h"
#include "goo.h"
int main(int argc, char** argv) {
  namespace_struct const * const xoo = (argc > 1 ? foo : goo);
  xoo->baz();
  printf("%d", xoo->bar(3, "hello"));
  return 0;
}

The multiple definitions of my_bar and my_baz don't conflict, since they're defined statically, but the underlying functions are still accessible through the appropriate namespace struct.

rampion
+6  A: 

When using namespace prefixes, I normally add macros for the shortened names which can be activated via #define NAMESPACE_SHORT_NAMES before inclusion of the header. A header foobar.h might look like this:

// inclusion guard
#ifndef _FOOBAR_H
#define _FOOBAR_H

// long names
void foobar_some_func(int);
void foobar_other_func();

// short names
#ifdef FOOBAR_SHORT_NAMES
#define some_func(...) foobar_some_func(__VA_ARGS__)
#define other_func(...) foobar_other_func(__VA_ARGS__)
#endif

#endif

If I want to use short names in an including file, I'll do

#define FOOBAR_SHORT_NAMES
#include "foobar.h"

I find this a cleaner and more useful solution than using namespace macros as described by Vinko Vrsalovic (in the comments).

Christoph
I like this approach, because it preserves the usual syntax for declaring and calling functions and it also saves me some typing. This might be a matter of personal preference, but I think this is the most readable solution.
Kim