1

I don't quite understand the concepts behind using the extern and const keywords in C++.

I've read a few related questions on the subject ( see below ), but so far I haven't been able to get a grasp on how to use them together.

Related Questions:

Ok, take for example the following program code:

dConst.hpp

extern const int NUM_GENERATORS;    // Number of generators in power plant

extern const int generatorID[NUM_GENERATORS];   // Generator ID numbers
extern const bool generatorStatus[NUM_GENERATORS];  // Generator Status

vConst.cpp

const int NUM_GENERATORS = 4;       // Generators in Power Plant

const int generatorID[NUM_GENERATORS] = // Generator ID numbers
{
    23, 57, 49, 106
};      
const bool generatorStatus[NUM_GENERATORS] =    // Production status ( online? )
{
    true, false, false, true
};

main.cpp

#include <iostream>
#include "dConst.hpp"

using std::cout;
using std::cin;
using std::endl;

//  ----====<  M A I N  >====----
int main()
{
    for ( int iGenerator = 0; iGenerator < NUM_GENERATORS; iGenerator++ )
    {
        cout << "Generator ";
        cout << generatorID[iGenerator];

        if ( generatorStatus[iGenerator] )
            cout << "is running." << endl;
        else
            cout << "is offline!" << endl;
    }

    cout << "Press ENTER to EXIT:";
    cin.get();  // Stop 

    return 0;
}

I am unable to use NUM_GENERATORS to declare my arrays full of generator ID's and statuses. I've included the external definitions at the top: #include "dConst.hpp. From what I've read ( perhaps not closely enough ) on some of the StackOverflow questions here, the compiler and linker should be able to find the values defined in vConst.cpp, and continue on their merry way.

So why aren't they doing this?

Community
  • 1
  • 1

2 Answers2

2

The linker can find it, but the compiler can't, since it is in a different compilation unit. The compiler needs to know the size of the array at compile time, but it will only be known at link time if the constant is declared extern.

Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
  • So I would need to include the declaration for those constants in *vConst.cpp* into *main.cpp*. If I have to use those same constants in another source file though, such as *powerPlant.cpp*, wouldn't I end up with a redeclaration of those constants [One Definition Rule](http://stackoverflow.com/questions/4192170/what-exactly-is-one-definition-rule-in-c)? – gate_engineer Nov 23 '13 at 23:03
2

Mr. Pollex is exactly right, however I thought I might expand on his answer so that folks looking for this information in the future might have a more complete picture. Often modern IDE's obscure the multiple parts involved in converting source code into executable binary.

Broadly speaking the C/C++ compiler only deals with text files (source files). The compiler reads these files, parses them and outputs object files. Object files contain binary executable sections and symbol sections. The linker then runs to 'link' various binary object files into a single executable. It does this by matching the symbols requested with the symbols available.

In the case you have presented you are using the 'extern' keyword to tell the compiler that the value for the defined symbol is defined in a different object than the one generated by this source. This tells the compiler to generate an object that imports this symbol. The linker then takes care of matching up the imported/exported symbols from the objects. Because of this the value you are looking for isn't available when the compiler runs because it depends on an external symbol from another object (that may not have even been build at that point). There is no way for the compiler to know the value of the symbol, therefore it can't use it.

Dweeberly
  • 4,668
  • 2
  • 22
  • 41