0

I'm new with c++ and came across to this code:

File.h

namespace Type
{
   typedef BOOL (WINAPI *TYCopyFile)
   (
    PCHAR lpExistingFileName,
    PCHAR lpNewFileName,
    BOOL  bFailIfExists
   );
}

namespace Func
{
  extern Types::TYCopyFile pCopyFileA;
}

File.cpp

namespace Funcs
{
  Types::TYCopyFile pCopyFileA;
}

void Init
{
  Funcs::pCopyFileA = (Types::T_CopyFile) GetProcAddress(hKernel32, "CopyFileA");
}

The idea is real simple. I have namespace of typedef(Types) and create function pointer in another namespace(Funcs) as extern. Then I define that function pointer in File.cpp in Init function.

The question that I have is that why do I need to redeclare namespace Funcs in File.cpp? Why can't I just have Init function which would initialize Funcs::pCopyFileA? As I understand extern, it tells compiler that the variable exists somewhere and tell linker to find it. Why can't linker find it without namespace Funcs in File.cpp?

user3503143
  • 381
  • 3
  • 10

1 Answers1

1

For all symbols in C++ you need both a declaration and a definition. The header file contains the declaration of Func::pCopyFileA, the source file contains the definition.

If you define the variable in the header file (i.e. you remove the extern keyword) then the definition would be done in all translation units that include the header file. This breaks the one definition rule, and would lead to multiple-definition errors when linking.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 1
    Although they could use `inline` if they have C++17 so they can define and declare it in the header file. – NathanOliver May 13 '19 at 12:40
  • 1
    so without `extern` I redefine same variable multiple times right? – user3503143 May 13 '19 at 13:27
  • @user3503143 Yes that's correct. Adding the `extern` keyword makes it a declaration instead of a definition. And you can declare a variable how many times you want (as long as you declare it the same way). – Some programmer dude May 13 '19 at 13:34