linkage of c++ const globals?

Viewed 67

I have 5 files: a.h:

extern const int a;

a.cpp:

#include "a.h"
const int a = 1;

b.h:

extern const int a;
extern const int b;

b.cpp:

#include "b.h"
const int b = a + 1;

main.cpp:

#include <stdio.h>
#include "a.h"
#include "b.h"
int c = a + 1;
int d = b + 1;
int main() {
  printf("c: %d\n", c);
  printf("d: %d\n", d);
  return 0;
}

I compile them with the following order:

gcc -c *.cpp
gcc a.o b.o main.o -o after
gcc main.o a.o b.o -o before

When I run after and before:

./after
c: 2
d: 3

./before
c: 2
d: 1

Someone else can explain the linkage of these globals?

1 Answers

By default, a global const has internal linkage, but you've nullified it with the extern declarations so a and b have the external linkage that you want. (If they didn't, your program wouldn't link!)

However, due to the static initialisation order fiasco, you don't know what order those constants are going to be initialised in. They'll be top-to-bottom within a translation unit, of course, but across translation units all bets are off. You're able to observe some of those shenanigans by altering the link order.

Try to avoid code like this; various approaches exist for your redesign.

Related