views:

367

answers:

8

Introduction

Hello folks, I recently learned to program in C! (This was a huge step for me, since C++ was the first language, I had contact with and scared me off for nearly 10 years.) Coming from a mostly OO background (Java + C#), this was a very nice paradigm shift.

I love C. It's such a beautiful language. What surprised me the most, is the high grade of modularity and code reusability C supports - of course it's not as high as in a OO-language, but still far beyond my expectations for an imperative language.

Question

How do I prevent naming conflicts between the client code and my C library code? In Java there are packages, in C# there are namespaces. Imagine I write a C library, which offers the operation "add". It is very likely, that the client already uses an operation called like that - what do I do?

I'm especially looking for a client friendly solution. For example, I wouldn't like to prefix all my api operations like "myuniquelibname_add" at all. What are the common solutions to this in the C world? Do you put all api operations in a struct, so the client can choose its own prefix?

I'm very looking forward to the insights I get through your answers!

EDIT (modified question)

Dear Answerers, thank You for Your answers! I now see, that prefixes are the only way to safely avoid naming conflicts. So, I would like to modifiy my question: What possibilities do I have, to let the client choose his own prefix?

The answer Unwind posted, is one way. It doesn't use prefixes in the normal sense, but one has to prefix every api call by "api->". What further solutions are there (like using a #define for example)?

EDIT 2 (status update)

It all boils down to one of two approaches:

  • Using a struct
  • Using #define (note: There are many ways, how one can use #define to achieve, what I desire)

I will not accept any answer, because I think that there is no correct answer. The solution one chooses rather depends on the particular case and one's own preferences. I, by myself, will try out all the approaches You mentioned to find out which suits me best in which situation. Feel free to post arguments for or against certain appraoches in the comments of the corresponding answers.

Finally, I would like to especially thank:

  • Unwind - for his sophisticated answer including a full implementation of the "struct-method"
  • Christoph - for his good answer and pointing me to Namespaces in C
  • All others - for Your great input

If someone finds it appropriate to close this question (as no further insights to expect), he/she should feel free to do so - I can not decide this, as I'm no C guru.

+4  A: 

It's a shame you got scared off by C++, as it has namespaces to deal with precisely this problem. In C, you are pretty much limited to using prefixes - you certainly can't "put api operations in a struct".

Edit: In response to your second question regarding allowing users to specify their own prefix, I would avoid it like the plague. 99.9% of users will be happy with whatever prefix you provide (assuming it isn't too silly) and will be very UNHAPPY at the hoops (macros, structs, whatever) they will have to jump through to satisfy the remaining 0.1%.

anon
Why so down on using a struct as a namespace? Just make a struct of function pointers and it looks very similar to static class methods. This defeats a bunch of optimizations, but also gives you more control and opens up interesting state management options.
Ken Fox
How many libraries do you know that take this route?
anon
About all of them in Windows. COM interfaces.
Hans Passant
I must admit I thought the OP was asking about "plain old" C libraries like SQLite or ncurses. Also, I do a fair bit of Windows programming, but never use COM, so I guess not "about all of them."
anon
@Neil: Thx for editing Your answer. I appreciate Your opinion
Dave
@Ken Fox: Could You elaborate on "state management options"? Thx in advance.
Dave
+9  A: 

I'm no C guru, but from the libraries I have used, it is quite common to use a prefix to separate functions.

For example, SDL will use SDL, OpenGL will use gl, etc...

phtrivier
+1: Prefixes are your only choice.
S.Lott
+2  A: 

Unfortunately, there's no sure way to avoid name clashes in C. Since it lacks namespaces, you're left with prefixing the names of global functions and variables. Most libraries pick some short and "unique" prefix (unique is in quotes for obvious reasons), and hope that no clashes occur.

One thing to note is that most of the code of a library can be statically declared - meaning that it won't clash with similarly named functions in other files. But exported functions indeed have to be carefully prefixed.

Eli Bendersky
+1  A: 

Since you are exposing functions with the same name client cannot include your library header files along with other header files which have name collision. In this case you add the following in the header file before the function prototype and this wouldn't effect client usage as well.

#define add myuniquelibname_add

Please note this is a quick fix solution and should be the last option.

Andy
Wouldn't I rather prefix all my exposed api operations by a "unique" prefix and then let the client do(for example): #define $ myuniquelibname, so he then could do something like "$_add(...)", instead of "myunique.._add(...)"? Plus: Why do You consider that the last option?
Dave
@Dave: $_add(...) won't work as the identifier is not a C token. I would have the #define in the library header file instead of the client. From the usability aspect client wants add functionality by calling add(), client doesn't want to consider about symbol collision. By including the appropriate header files the add function from the library should be invoked. As we expect the client to use only one header file and ensure that header files from two libraries with name collision are not included. This would invariably lead to some maintenance issues in future.
Andy
I see, thx for the clarification
Dave
+5  A: 

The struct way that Ken mentions would look something like this:

struct MyCoolApi
{
  void (*add)(int x, int y);
};

MyCoolApi * my_cool_api_initialize(void);

Then clients would do:

#include <stdio.h>
#include <stdlib.h>

#include "mycoolapi.h"

int main(void)
{
  struct MyCoolApi *api;

  if((api = my_cool_api_initialize()) != NULL)
  {
    int sum = api->add(3, 39);

    printf("The cool API considers 3 + 39 to be %d\n", sum);
  }
  return EXIT_SUCCESS;
}

This still has "namespace-issues"; the struct name (called the "struct tag") needs to be unique, and you can't declare nested structs that are useful by themselves. It works well for collecting functions though, and is a technique you see quite often in C.

UPDATE: Here's how the implementation side could look, this was requested in a comment:

#include "mycoolapi.h"

/* Note: This does **not** pollute the global namespace,
 * since the function is static.
*/
static int add(int x, int y)
{
  return x + y;
}

struct MyCoolApi * my_cool_api_initialize(void)
{
  /* Since we don't need to do anything at initialize,
   * just keep a const struct ready and return it.
  */
  static const struct MyCoolApi the_api = {
    add
  };

  return &the_api;
}
unwind
@unwind: Thx for the insight. I see the additional work involved with this solution and its limits. Though the nice thing is, that the client can choose his own "prefix"("api" in your example). 2 questions: Could you provide the implementation for "my_cool_api_initialize"? Are there other ways to let the client choose his own prefix (using #define)?
Dave
@Dave: Done! :)
unwind
Why initialize the api structure at runtime? Just use an initializer in `my_cool_api_initialize()`, and while at it, make the structure `const` so compilers with link-time optimizations can inline the function pointers; you might even want to define the function in a `.h` file to make this possible even for compilers without link-time optimizations...
Christoph
@Christoph: I was being a bit general-purpose; perhaps the API would need to do something at run-time. I chopped it out, now the implementation is more minimal.
unwind
@unwind: Thank You for the effort.
Dave
A: 

Prefixes are only choice on C level.

On some platforms (that support separate namespaces for linkers, like Windows, OS X and some commercial unices, but not Linux and FreeBSD) you can workaround conflicts by stuffing code in a library, and only export the symbols from the library you really need. (and e.g. aliasing in the importlib in case there are conflicts in exported symbols)

Marco van de Voort
+1  A: 

For a really huge example of the struct method, take a look at the Linux kernel; 30-odd million lines of C in that style.

Andrew McGregor
linux doesn't use that for name collision issues, it uses for reproducing virtual functions and similar. For example the VFS is based on structs with function pointers for the operations which are different for each filesystem type.
Evan Teran
+1  A: 

As a library user, you can easily define your own shortened namespaces via the preprocessor; the result will look a bit strange, but it works:

#define ns(NAME) my_cool_namespace_ ## NAME

makes it possible to write

ns(foo)(42)

instead of

my_cool_namespace_foo(42)

As a library author, you can provide shortened names as desribed here.

If you follow unwinds's advice and create an API structure, you should make the function pointers compile-time constants to make inlinig possible, ie in your .h file, use the follwoing code:

// canonical name
extern int my_cool_api_add(int x, int y);

// API structure
struct my_cool_api
{
    int (*add)(int x, int y);
};

typedef const struct my_cool_api *MyCoolApi;

// define in header to make inlining possible
static MyCoolApi my_cool_api_initialize(void)
{
    static const struct my_cool_api the_api = { my_cool_api_add };
    return &the_api;
}
Christoph
+1: Thank You for this good answer.
Dave