hardboiled65
hardboiled65

Reputation: 321

Is it posible to declare global function in namespace

I am making a resource system that similar to Qt's qrc.

The resource is automatically created to .c file contains byte array. And it compiled to static library.

And it has a header file looks like below. I don't know which hash value comes so I defined a macro function.

#ifndef BRC_6c26e83425a54300d410b49c1aa1c3ea
#define BRC_6c26e83425a54300d410b49c1aa1c3ea

void bl_register_resource_6c26e83425a54300d410b49c1aa1c3ea();

#ifdef BL_REGISTER_RESOURCE
    #undef BL_REGISTER_RESOURCE
#endif
#define BL_REGISTER_RESOURCE() \
    bl_register_resource_6c26e83425a54300d410b49c1aa1c3ea();

#endif

It is intended to use as

void init_function()
{
    #include "path/to/resource/resource.h"
    BL_REGISTER_RESOURCE()

    // Resource is registered in global singleton object
    // and now I can access the resource from it.

    #include "path/to/resource/another.h"
    BL_REGISTER_RESOURCE()

    // Another resource register function is called.
}

It worked find when I use C. But the code base has moved to C++, now I can't use this trick because include and call macro function may happened in C++ namespace.

namespace my {

MyClass::MyClass()
{
    #include "path/to/resource/resource.h"
    BL_REGISTER_RESOURCE()
}

} // namespace my

I found that I can't use extern "C" in function definition. The function declaration void bl_register_resource_HASH(); will be my::bl_register_resource_HASH(); but the function definition has no namespace. This causes "undefined reference to my::bl_register_resource_HASH()".

Include the header outside of namespace works fine. But in this time I can't use multiple macro call trick.

I tried void ::bl_register_resource_HASH(); but it doesn't worked.

Is there any way to declare global scope function in namespace?

Upvotes: 0

Views: 111

Answers (1)

3CxEZiVlQ
3CxEZiVlQ

Reputation: 38518

I see the only simple way is

#ifndef BRC_6c26e83425a54300d410b49c1aa1c3ea
#define BRC_6c26e83425a54300d410b49c1aa1c3ea

void bl_register_resource_6c26e83425a54300d410b49c1aa1c3ea();

#endif

#ifdef BL_REGISTER_RESOURCE
    #undef BL_REGISTER_RESOURCE
#endif
#define BL_REGISTER_RESOURCE() \
    ::bl_register_resource_6c26e83425a54300d410b49c1aa1c3ea();

And usage

#include "path/to/resource/resource.h"
#include "path/to/resource/other.h"

namespace my {

MyClass::MyClass()
{
    #include "path/to/resource/resource.h"
    BL_REGISTER_RESOURCE()

    #include "path/to/resource/other.h"
    BL_REGISTER_RESOURCE()
}

}

I have moved #endif to make repeated #include being able to define the macro BL_REGISTER_RESOURCE()

Function like macros require special settings in clang-format. It is better

#define BL_REGISTER_RESOURCE() \
    ::bl_register_resource_6c26e83425a54300d410b49c1aa1c3ea()

BL_REGISTER_RESOURCE();

Upvotes: 1

Related Questions