External linkage is a property of an identifier that makes it visible to other translation units. In simpler terms, defining an identifier with external linkage in a file is visible to other files. If there are multiple same name identifiers in different files, it violates ODR and causes duplicate compilation error.

Non-constant global variables have external linkage property by default. Constant global variables have internal linkage property. We can use extern keyword to make constant global variables external.

lib.cpp

int value{1};
 
extern const double pi{3.14};

Note

We do not require to use extern with non-constant variables as they are external by default.

Using external variables

To use them, we need to forward declare them as we do with functions. We can use extern keyword to forward declare them.

main.cpp

#include "../helpers/stdout.h"
 
extern int value;
extern double pi;
 
int main(int argc, char const *argv[])
{
    print(value);
    print(pi);
    return 0;
}

This way, compiler knows that there are variables defined somewhere else to be used here. Linker then links their definitions.

Avoid using extern with non-constant global variable definitions

If we do something like below,

lib.cpp

extern int value{1};

and compile the program, it should give following warning.

lib.cpp:1:12: warning: 'value' initialized and declared 'extern'
    1 | extern int value{1};
      |            ^~~~~

Global variables have external linkage by default, using extern with definition is ambiguous for compiler to make think it is forward declaration.

References

  1. https://www.learncpp.com/cpp-tutorial/external-linkage-and-variable-forward-declarations/