OK, this following example code demonstrates the difference between a strong and weak linker reference. After I will try to explain why changing between the 2 can alter the resulting executable created by a linker.
prototypes.h
class CLASS
{
public:
static const int global;
};
template <class T>
class TEMPLATE
{
public:
static const int global;
};
void part1();
void part2();
file1.cpp
#include <iostream>
#include "template.h"
const int CLASS::global = 11;
template <class T>
const int TEMPLATE<T>::global = 21;
void part1()
{
std::cout << TEMPLATE<int>::global << std::endl;
std::cout << CLASS::global << std::endl;
}
file2.cpp
#include <iostream>
#include "template.h"
const int CLASS::global = 21;
template <class T>
const int TEMPLATE<T>::global = 22;
void part2()
{
std::cout << TEMPLATE<int>::global << std::endl;
std::cout << CLASS::global << std::endl;
}
main.cpp
#include <stdio.h>
#include "template.h"
void main()
{
part1();
part2();
}
I accept this example is totally contrived, but hopefully it demonstrates why 'Changing strong to weak linker references is a breaking change'.
Will this compile? No, because it has 2 strong references to CLASS::global.
If you remove one of the strong references to CLASS::global, will it compile? Yes
What is the value of TEMPLATE::global?
What is the value of CLASS::global?
The weak reference is undefined because it depends on the link order, which makes it obscure at best and depending on the linker uncontrollable. This is probably acceptable because it is uncommon not to keep all of the template in a single file, because both prototype and implementation are required together for compilation to work.
However, for Class Static Data Members as they were historically strong references, and not definable within the declaration, it was the rule, and now at least common practice to have the full data declaration with the strong reference in the implementation file.
In fact, because of the linker producing ODR link errors for violations of strong references, it was common practice to have multiple object files (compilation units to be linked), that were linked conditionally to alter behaviour for different hardware and software combinations and sometimes for optimization benefits. Knowing if you made a mistake in your link parameters, you would get an error either saying you had forgotten to select a specialization (no strong reference), or had selected multiple specializations (multiple strong references)
You need to remember at the time of the introduction of C++, 8 bit, 16 bit and 32 bit processors were all still valid targets, AMD and Intel had similar but different instruction sets, hardware vendors preferred closed private interfaces to open standards. And the build cycle could take hours, days, even a week.