Question

I am simply writing a function that I want to use in my code for debugging WITHOUT throwing exceptions. I want a defined variable DEBUG_MODE that when set to true causes the function to print a given message and when set to false prints nothing. I want it available to any class that imports the file without having to create a class, i.e. I include "Debug.h" and can call Debug::Log(string message).

I read about the advantages of using namespace functions so I wrote it as such but perhaps I don't understand the proper usage of namespace functions. When I include my header file with the namespace function in one class it works great, when I use it in two classes in two different files I get a linker error:

Error   1   error LNK2005: "void __cdecl Debug::Log(char const *)" (?Log@Debug@@YAXPBD0@Z) already defined in Foo.obj...

Here is the code for my namespace functions:

#pragma once

#include <cstdio>

// IMPORTANT: Set this to true if you want debug logging, false otherwise
#define DEBUG_MODE true

namespace Debug
{
    void Log(const char* message)
    {
        if (DEBUG_MODE)
            printf(message);
    }

    void Log(const char* messageFormat, const char* parameter)
    {
        if (DEBUG_MODE)
            printf(messageFormat, parameter);
    }
}

Now if I make the functions static then everything works fine, but I was under the impression that using namespace functions was the alternative to static functions in my case. I would also like to be able to define static functions in another file if possible.

What should I use? A static function? A namespace function? If the latter then how do I use namespace functions in two separate classes/files without causing the above linker error?

Was it helpful?

Solution

All you are missing is the inline keyword like so:

inline void Log(const char* message)

Without inline, the functions are created for each source file including your header file.

static would have a similar outcome, but inlining seems preferred for such a small functions.


Or, if you don't want to make the compiler create the code again and again in all files, you of course need to have the implementation just once in one .cpp file and leave just the declaration in the header.

In order for the DEBUG_MODE to affect it, though, you will need to do it e.g. like this:

#ifndef DEBUG_MODE

// Dummy implementation
inline void Log(...) {}

#else

// Implemented in Log.cpp
void Log(const char* message);
void Log(const char* messageFormat, const char* parameter);

#endif

OTHER TIPS

Try making them inline. Otherwise you could define them in a separate source file and just declare them in the header file.

If you define it in the header as a non-inline non-static function and include it in more than one source file of a program, the linker will be presented with copies of the same function in multiple object files.

There are 3 solutions:

  1. Make them inline.
  2. Make them static.
  3. Define them in their own source file and only declare them in the header file.

Making them static causes the names not to be exported and they are therefore only known inside one object file. But you will still have multiple copies of the functions, but only one copy each in each object file that uses them.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top