Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Include implementation file inside namespace to avoid name clashing

I am making a C++ wrapper around a C library. Let's say that the library (let's call it Clib) defines a function like this:

// clib.h
const char* clib_foo(clib_obj_t* obj);

In my wrapper I have the following:

// clibpp.h
#include <clib.h>

namespace clib {
    std::string_view foo(const clib::obj_t& obj) {
        return clib_foo(obj.raw());
    };
}

// symbols from both clib.h and clibpp.h visible

Now, my wrapper is header only. So when someone includes clibpp.h they see symbols from both clibpp.h and clib.h. I want to avoid that. my idea is to include the clib.h header inside a namespace in the clibpp.h header to hide all the symbols.

// clibpp.h
namespace clib {
    namespace detail {
        #include <clib.h>
    }
    std::string_view foo(const clib::obj_t& obj) {
        return detail::clib_foo(obj.raw());
    };
}

// symbols from only clibpp.h visible (apart from preprocessor definitions)

Is this a good idea or possible to do? Why doesn't anybody seem to do it?

like image 392
janekb04 Avatar asked Feb 16 '26 14:02

janekb04


1 Answers

Is this a good idea or possible to do?

No, that won't work because the C library - for obvious reasons - doesn't define the functions etc. within that namespace.

Why doesn't anybody seem to do it?

Because it doesn't work.


If you give up the desire to have a header-only wrapper library, then you can avoid "leaking" the C header since you could include it only within a translation unit of the wrapper library.

Note that this still doesn't solve all problems with name clashes since One Definition Rule applies across translation unit boundaries. If you link with a C library, then the external names of that library cannot be used by anything else. Hiding the C header does prevent macro-pollution.

like image 168
eerorika Avatar answered Feb 18 '26 06:02

eerorika