1

Please suggest me a hint over here:

class UIClass
{
public:
    UIClass::UIClass();
};

#ifndef __PLATFORM__
#define __PLATFORM__
    UIClass Platform;
#else
    extern UIClass Platform;
#endif

I'm including this two times and getting:

LNK2005 - Platform already defined in .obj (MSVS13).

As you can guess, the idea was to define Platform only once. Why does #ifndef or #define fail? How should I fix this?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
MixMix
  • 99
  • 8
  • 3
    Because you have more than one `cpp` file that defines `__PLATFORM__` causing `Platform` to be defined in multiple object files. The identifier `__PLATFORM__` is reserved for use by the implementation (compiler, libraries, etc.). See http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier for more detailed information. – Captain Obvlious Jan 06 '14 at 17:10

1 Answers1

8

#define's are translation unit-local, but definitions are not. You need to put extern UIClass Platform; in your header and UIClass Platform; in an implementation file.

If you really want to have the definition in your header you can use some template class magic:

namespace detail {
    // a template prevents multiple definitions
    template<bool = true>
    class def_once_platform {
        static UIClass Platform;
    };

    // define instance
    template<bool _> def_once_platform<_> def_once_platform<_>::Platform;

    // force instantiation
    template def_once_platform<> def_once_platform<>::Platform;
}

// get reference
UIClass& Platform = detail::def_once_platform<>::Platform;
orlp
  • 112,504
  • 36
  • 218
  • 315