In the sample program below,
Why is the output different for static & automatic variable of user defined class type ?
/* test.cpp */
/* SalesData Class */
class SalesData {
public:
SalesData() = default;
// other member funcations
private:
std::string bookNo;
unsigned int unitsSold;
double revenue;
};
/*
* Prints the SalesData object
*/
std::ostream& print(std::ostream &os, const SalesData &item) {
os << "ISBN :\'" << item.isbn() << "\', Units Sold :" << item.unitsSold
<< ", Revenue :" << item.revenue << ", Avg. Price :"
<< item.avgPrice() << std::endl;
return os;
}
int main(int argc, char *argv[]) {
SalesData s;
static SalesData s2;
print(cout, s);
print(cout, s2);
return 0;
}
Output of the program is this --
$ ./test
ISBN :'', Units Sold :3417894856, Revenue :4.66042e-310, Avg. Price :1.36352e-319
ISBN :'', Units Sold :0, Revenue :0, Avg. Price :0
How is static changing the scene in synthesized default constructor ?
CodePudding user response:
Variables with static storage duration are zero-initialised before their dynamic initialisation phase.
unitsSold and revenue are default initialised. That leaves them uninitialised. In the case of static storage, the previous zero initialisation holds. In the case of automatic storage, they have an indeterminate value. Reading the indeterminate value results in undefined behaviour of the program.
CodePudding user response:
The default constructor has the same behavior on s and s2. The difference is, for static local variables,
Variables declared at block scope with the specifier static
or thread_local (since C 11)have staticor thread (since C 11)storage duration but are initialized the first time control passes through their declaration (unless their initialization is zero- or constant-initialization, which can be performed before the block is first entered).
and about zero-initialization:
For every named variable with static
or thread-local (since C 11)storage duration that is not subject to constant initialization, before any other initialization.
That means s2 will be zero-initialized firstly, as the effect its data members are zero-initialized too; then enterning main() it's default-initialized via the default constructor.
