Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6235299
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 24, 20262026-05-24T10:38:45+00:00 2026-05-24T10:38:45+00:00

One of the most important rules and best practices when writing a library, is

  • 0

One of the most important rules and best practices when writing a library, is putting all symbols of the
library into a library specific namespace. C++ makes this easy, due to the namespace keyword. In
C the usual approach is to prefix the identifiers with some library specific prefix.

Rules of the C standard put some constraints on those (for safe compilation): A C compiler may look at only the first
8 characters of an identifier, so foobar2k_eggs and foobar2k_spam may be interpreted as the same
identifiers validly – however every modern compiler allows for arbitrary long identifiers, so in our times
(the 21st century) we should not have to bother about this.

But what if you’re facing some libraries of which you cannot change the symbol names / idenfiers? Maybe you got
only a static binary and the headers or don’t want to, or are not allowed to adjust and recompile yourself.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-24T10:38:46+00:00Added an answer on May 24, 2026 at 10:38 am

    At least in the case of static libraries you can work around it quite conveniently.

    Consider those headers of libraries foo and bar. For the sake of this tutorial I’ll also give you the source files

    examples/ex01/foo.h

    int spam(void);
    double eggs(void);
    

    examples/ex01/foo.c (this may be opaque/not available)

    int the_spams;
    double the_eggs;
    
    int spam()
    {
        return the_spams++;
    }
    
    double eggs()
    {
        return the_eggs--;
    }
    

    example/ex01/bar.h

    int spam(int new_spams);
    double eggs(double new_eggs);
    

    examples/ex01/bar.c (this may be opaque/not available)

    int the_spams;
    double the_eggs;
    
    int spam(int new_spams)
    {
        int old_spams = the_spams;
        the_spams = new_spams;
        return old_spams;
    }
    
    double eggs(double new_eggs)
    {
        double old_eggs = the_eggs;
        the_eggs = new_eggs;
        return old_eggs;
    }
    

    We want to use those in a program foobar

    example/ex01/foobar.c

    #include <stdio.h>
    
    #include "foo.h"
    #include "bar.h"
    
    int main()
    {
        const int    new_bar_spam = 3;
        const double new_bar_eggs = 5.0f;
    
        printf("foo: spam = %d, eggs = %f\n", spam(), eggs() );
        printf("bar: old spam = %d, new spam = %d ; old eggs = %f, new eggs = %f\n", 
                spam(new_bar_spam), new_bar_spam, 
                eggs(new_bar_eggs), new_bar_eggs );
    
        return 0;
    }
    

    One problem becomes apparent immediately: C doesn’t know overloading. So we have two times two functions with
    identical name but of different signature. So we need some way to distinguish those. Anyway, lets see what a
    compiler has to say about this:

    example/ex01/ $ make
    cc    -c -o foobar.o foobar.c
    In file included from foobar.c:4:
    bar.h:1: error: conflicting types for ‘spam’
    foo.h:1: note: previous declaration of ‘spam’ was here
    bar.h:2: error: conflicting types for ‘eggs’
    foo.h:2: note: previous declaration of ‘eggs’ was here
    foobar.c: In function ‘main’:
    foobar.c:11: error: too few arguments to function ‘spam’
    foobar.c:11: error: too few arguments to function ‘eggs’
    make: *** [foobar.o] Error 1
    

    Okay, this was no surprise, it just told us, what we already knew, or at least suspected.

    So can we somehow resolve that identifer collision without modifying the original libraries’
    source code or headers? In fact we can.

    First lets resolve the compile time issues. For this we surround the header includes with a
    bunch of preprocessor #define directives that prefix all the symbols exported by the library.
    Later we do this with some nice cozy wrapper-header, but just for the sake of demonstrating
    what’s going on were doing it verbatim in the foobar.c source file:

    example/ex02/foobar.c

    #include <stdio.h>
    
    #define spam foo_spam
    #define eggs foo_eggs
    #  include "foo.h"
    #undef spam
    #undef eggs
    
    #define spam bar_spam
    #define eggs bar_eggs
    #  include "bar.h"
    #undef spam
    #undef eggs
    
    int main()
    {
        const int    new_bar_spam = 3;
        const double new_bar_eggs = 5.0f;
    
        printf("foo: spam = %d, eggs = %f\n", foo_spam(), foo_eggs() );
        printf("bar: old spam = %d, new spam = %d ; old eggs = %f, new eggs = %f\n", 
               bar_spam(new_bar_spam), new_bar_spam, 
               bar_eggs(new_bar_eggs), new_bar_eggs );
    
        return 0;
    }
    

    Now if we compile this…

    example/ex02/ $ make
    cc    -c -o foobar.o foobar.c
    cc   foobar.o foo.o bar.o   -o foobar
    bar.o: In function `spam':
    bar.c:(.text+0x0): multiple definition of `spam'
    foo.o:foo.c:(.text+0x0): first defined here
    bar.o: In function `eggs':
    bar.c:(.text+0x1e): multiple definition of `eggs'
    foo.o:foo.c:(.text+0x19): first defined here
    foobar.o: In function `main':
    foobar.c:(.text+0x1e): undefined reference to `foo_eggs'
    foobar.c:(.text+0x28): undefined reference to `foo_spam'
    foobar.c:(.text+0x4d): undefined reference to `bar_eggs'
    foobar.c:(.text+0x5c): undefined reference to `bar_spam'
    collect2: ld returned 1 exit status
    make: *** [foobar] Error 1
    

    … it first looks like things got worse. But look closely: Actually the compilation stage
    went just fine. It’s just the linker which is now complaining that there are symbols colliding
    and it tells us the location (source file and line) where this happens. And as we can see
    those symbols are unprefixed.

    Let’s take a look at the symbol tables with the nm utility:

    example/ex02/ $ nm foo.o
    0000000000000019 T eggs
    0000000000000000 T spam
    0000000000000008 C the_eggs
    0000000000000004 C the_spams
    
    example/ex02/ $ nm bar.o
    0000000000000019 T eggs
    0000000000000000 T spam
    0000000000000008 C the_eggs
    0000000000000004 C the_spams
    

    So now we’re challenged with the exercise to prefix those symbols in some opaque binary. Yes, I know
    in the course of this example we have the sources and could change this there. But for now, just assume
    you have only those .o files, or a .a (which actually is just a bunch of .o).

    objcopy to the rescue

    There is one tool particularily interesting for us: objcopy

    objcopy works on temporary files, so we can use it as if it were operating in-place. There is one
    option/operation called –prefix-symbols and you have 3 guesses what it does.

    So let’s throw this fella onto our stubborn libraries:

    example/ex03/ $ objcopy --prefix-symbols=foo_ foo.o
    example/ex03/ $ objcopy --prefix-symbols=bar_ bar.o
    

    nm shows us that this seemed to work:

    example/ex03/ $ nm foo.o
    0000000000000019 T foo_eggs
    0000000000000000 T foo_spam
    0000000000000008 C foo_the_eggs
    0000000000000004 C foo_the_spams
    
    example/ex03/ $ nm bar.o
    000000000000001e T bar_eggs
    0000000000000000 T bar_spam
    0000000000000008 C bar_the_eggs
    0000000000000004 C bar_the_spams
    

    Lets try linking this whole thing:

    example/ex03/ $ make
    cc   foobar.o foo.o bar.o   -o foobar
    

    And indeed, it worked:

    example/ex03/ $ ./foobar 
    foo: spam = 0, eggs = 0.000000
    bar: old spam = 0, new spam = 3 ; old eggs = 0.000000, new eggs = 5.000000
    

    Now I leave it as an exercise to the reader to implement a tool/script that automatically extracts the
    symbols of a library using nm, writes a wrapper header file of the structure

    /* wrapper header wrapper_foo.h for foo.h */
    #define spam foo_spam
    #define eggs foo_eggs
    /* ... */
    #include <foo.h>
    #undef spam
    #undef eggs
    /* ... */
    

    and applies the symbol prefix to the static library’s object files using objcopy.

    What about shared libraries?

    In principle the same could be done with shared libraries. However shared libraries, the name tells it,
    are shared among multiple programs, so messing with a shared library in this way is not such a good idea.

    You will not get around writing a trampoline wrapper. Even worse you cannot link against the shared library
    on the object file level, but are forced to do dynamic loading. But this deserves its very own article.

    Stay tuned, and happy coding.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am writing a ruby on rails application and one of the most important
GUIs are one of the important areas in most of the software products. I
Java is object oriented programming language.Inheritance is one of most important features. We use
I've been working on a mysql database, and one of the most important tables
I've recently started using APC cache on our servers. One of the most important
One of the most important opportunity TDD gives us, from my point of view,
Often times convention is one of the most important design consideration for user interface.
I am a firm believer in the idea that one of the most important
I have a poorly designed database. One of the most important tables has 11,000+
One of the most important aspects of NIO is the ability to operate in

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.