I wonder, what could be a possible inherent difference between
A a;
and A a{};
(class A, no constructor)?
I was just playing with code, and found out something very interesting, where declaring a global class instance as A a;
was producing a different result compared to using A a{};
instead.
This is intriguing because I've understood that:
Declaring a class instance without initialization calls the default constructor (constructor with no parameters, if it exists).
a{}
is an expression that creates a class instance and calls the default constructor.
So, basically the same thing, but they did produce different results in a certain condition, although it's found in the realm of possible UB by breaking ODR.
My question is, how can a program produce a different result (even though it is a wrong code), if A a;
is strictly equivalent to A a{};
?
Logically, there should be some difference between their internal implementation to produce a different result, while everything else stays exactly the same. I wonder what that difference is.
I'm using Visual studio 2017.
//extern_src.cpp
class A {
public:
int a=24;
};
A extern_a; // << here, if i put {} at the end, different results comes out;
//src.cpp
#include <iostream>
class A {
public:
int a=3;
};
int main() {
extern A extern_a;
A a;
std::cout << a.a << " " << extern_a.a << std::endl;
return 0;
}
Without {}
, the code prints out 3 3
.
So for both a
and extern_a
, the constructor of class A, which is defined in src.cpp
, is called.
With {}
, the code prints out 3 24
. In this case, the constructor that's defined in extern_src.cpp
is called for extern_A
.
It seems like the default constructor is not immediately called, but only called later in the compile process in the first case (class instance declaration without {}
).
I do understand this is breaking ODR by having multiple definitions for a single class. But my question is, if A a;
is completely equivalent to A a{};
, as they are both calling the default constructor, then how can they ever produce a different result?