So yesterday I was looking on SO and could not find an answer to the following. This situation came from some come code I am working with, but here is the MCVE to demonstrate it.
I have a class A defined in A.h that just has one static const in it. I already initialized it in the header.
#ifndef A_H_
#define A_H_
class A {
public:
static const int test = 5;
~A(){};
};
#endif /* A_H_ */
I then have a class B that needs to access the public static const from class A. In this example it will deep copy the value to a vector.
#ifndef B_H_
#define B_H_
#include "A.h"
#include <vector>
#include <iostream>
class B {
private:
std::vector<int> testVec;
public:
B(){
testVec.push_back((const int)A::test);
//testVec.push_back(static_cast<const int>(A::test)); //Also works
//testVec.push_back(A::test); //Doesn't work without forward declaration of const int A::test in main or in this header
//(Compiler link error: undefined reference to `A::test')
std::cout<< testVec.front() << std::endl;
}
~B(){};
};
#endif /* B_H_ */
Then in main I simple call the constructor of class B.
#include "B.h"
int main() {
B b;
return 0;
}
//Does the cout from ctor of B and prints 5 to the screen.
My question is why does a normal cast or static cast allow me to access this static const variable that has not been forward declared. In normal code, I would forward declare the variable or declare it an extern since it has already been defined. What is the reason as to why the casting allows me to access this variable without a forward declaration? (This may seem like a simple question and may have a simple answer, but I am trying to further my knowledge here).
The output from the compiler link error is:
Invoking: Cygwin C++ Linker
g++ -o "S_Test_p1.exe" ./src/S_Test_p1.o
./src/S_Test_p1.o:S_Test_p1.cpp:(.rdata$.refptr._ZN1A4testE[.refptr._ZN1A4testE]+0x0): undefined reference to `A::test'
collect2: error: ld returned 1 exit status
make: *** [makefile:47: S_Test_p1.exe] Error 1
My main question here is why the casting works and not that the solution is to define A::test in main or in B.h (which I know works). I understand that would be accepted and proper. The main question is about the unaccepted way, which is casting. Behind the scenes why does casting work for linking?