Skip to main content

C project avoiding naming conflicts [Resolved]

I'm struggling to find pragmatic real-world advice on function naming conventions for a medium sized C library project. My library project is separated into a few modules and submodules with their own headers, and loosely follows an OO style (all functions take a certain struct as first argument, no globals etc). It's laid our something like:

MyLib
  - Foo
    - foo.h
    - foo_internal.h
    - some_foo_action.c
    - another_foo_action.c
    - Baz
      - baz.h
      - some_baz_action.c
  - Bar
    - bar.h
    - bar_internal.h
    - some_bar_action.c

Generally the functions are far too big to (for example) stick some_foo_action and another_foo_action in one foo.c implementation file, make most functions static, and call it a day.

I can deal with stripping my internal ("module private") symbols when building the library to avoid conflicts for my users with their client programs, but the question is how to name symbols in my library? So far I've been doing:

struct MyLibFoo;
void MyLibFooSomeAction(MyLibFoo *foo, ...);

struct MyLibBar;
void MyLibBarAnAction(MyLibBar *bar, ...);

// Submodule
struct MyLibFooBaz;
void MyLibFooBazAnotherAction(MyLibFooBaz *baz, ...);

But I'm ending up with crazy long symbol names (much longer than the examples). If I don't prefix the names with a "fake namespace", modules' internal symbol names all clash.

Note: I don't care about camelcase/Pascal case etc, just the names themselves.


Question Credit: Dan Halliday
Question Reference
Asked July 18, 2019
Posted Under: Programming
40 views
4 Answers

Prefixing (well, affixing) is really the only option. Some patterns you'll see are <library>_<name> (e.g., OpenGL, ObjC runtime), <module/class>_<name> (e.g. parts of Linux), <library>_<module/class>_<name> (e.g., GTK+). Your scheme is perfectly reasonable.

Long names aren't necessarily bad if they are predictable. The fact that you are ending up with crazy long names and functions that are too big to stick with related functions in a single source file raises different concerns. Do you have some more concrete examples?


credit: user2313838
Answered July 18, 2019

If you do want to avoid long prefixes, you can abbreviate library names like what Apple does in iOS and OS X:

  • NSString is a string from the NextStep roots of the OS
  • CALayer is a Core Animation layer

credit: mouviciel
Answered July 18, 2019

What about having a global structure variable prefilled with function pointers?

lib.h

#pragma once

typedef struct
{
    void (*doFoo)(int x);
    const char *(*doBar)(void *p);
} YourApi;

extern const YourApi yourApi;

lib.c:

#include "lib.h"

#include <stdio.h>

static void doFoo(int x)
{
    printf("Doing foo %d\n", x);
}

static const char *doBar(void *p)
{
    printf("Doing bar: %p\n", p);
    return "Hello";
}

const YourApi yourApi = {
    doFoo,
    doBar};

Harness:

#include "lib.h"

int main()
{
    yourApi.doFoo(42);
    yourApi.doBar("asd");
}

The static keyword limits the scope to the translation unit so it won't collide with others.

The user can then shorten it by using a pointer like YourApi *ya = &yourApi, then using ya->doFoo(...).

It also provides a nice way to mock your library for testing.


credit: Calmarius
Answered July 18, 2019
Your Answer