Search code examples
c++namespacesconstantsextern

C++ Referencing extern const within a namespace


I am trying to use the constant int SIZE that is declared in the TaxConstants.hpp namespace TAXCONSTANTS in other places in my project. When I try to compile, I get "undefined reference to 'SIZE' everywhere that SIZE is referenced.

file TaxConstants.hpp

#ifndef TaxConstants_hpp
#define TaxConstants_hpp


namespace TAXCONSTANTS
{
     extern const int SIZE = 4; // I have tried with and without extern
}

#endif //TAXCONSTANTS_HPP

main.cpp

#include <iostream>
#include "TaxConstants.hpp"
using namespace std;
using namespace TAXCONSTANTS;

int main()
{
extern const int SIZE;

// This is a struct defined in another file. It is a sample of my use for SIZE. I left out the #include above to simplify things. 
taxPayer payers[SIZE];  

//More code

return 0;
}

Additional info: this is a school project and my teach has made it a requirement to declare constants in the file TaxConstants.hpp in the namespace TAXCONSTANTS.

There are 5 files in total, the file with my functions is having the same undefined reference to SIZE error.

I have spent hours looking up similar explanations on the extern function and namespaces, but most of the suggestions are against doing this in the first place an offer another solution. I, unfortunately can not use them. Other errors people had were getting "multiple decorations" which I am not having.

EDIT

See Brians explanation below for better detail.

What I needed to do was define

const int SIZE = 4;

within the TaxConstants.hpp file in namespace TAXCONSTANTS.

Then remove 'extern const int SIZE;' from my main file and instead reference SIZE by TAXCONSTANTS::SIZE everywhere I wanted to use size.

This is basic namespace stuff that I completely forgot about.


Solution

  • If you define SIZE without the extern keyword, it will have internal linkage since it is const. You can refer to it inmain.cpp as TAXCONSTANTS::SIZE. This is recommended since the compiler will be able to inline the value wherever SIZE is used.

    If you define SIZE with the extern keyword, it will have external linkage and it should not be in a header, unless you want multiple definition errors. You should instead define it in a .cpp file which will be linked into the rest of the program. In this case there will be only one copy of SIZE in the entire program. You should avoid this approach (preferring instead the approach without extern) unless for some reason you actually need to have only one copy of SIZE in the entire program.

    In both cases, SIZE will be a member of the TAXCONSTANTS namespace.

    Your attempt to redeclare SIZE inside main does not do what you think it does! The following inside main:

    extern const int SIZE;
    

    actually has the effect of declaring SIZE in the global namespace. Since there is no definition of SIZE in the global namespace, you get undefined reference errors at link time. It is not the correct way to refer to the SIZE variable defined in TAXCONSTANTS.