I'm a total newbie trying to learn C++ from a book. The code below works and produces output as expected, but there are warnings on the two lines that define engine
and randomInt
: "Initialization of 'engine' with static storage duration may throw an exception that cannot be caught."
If I put lines 7 and 8 inside of main()
, the warnings completely go away, but then engine
and randomInt
are not available to getNumber
.
I don't know how to fix the warnings. Also, perhaps more importantly, what is the proper approach for using randomInt
in various places besides main()
? Is it proper to declare it in main()
then pass it to functions as needed? Somehow main()
doesn't feel like the proper spot to be declaring these types of things.
I asked a question similar to this one earlier, but I'm still struggling to understand, and have provided an example that's hopefully useful.
// Loosely based on Fig. 6.12: fig06_12.cpp, C++ How To Program, Ninth Edition
#include <iostream>
#include <iomanip>
#include <random>
std::default_random_engine engine( static_cast<unsigned int>( time(nullptr) ) );
std::uniform_int_distribution<unsigned int> randomInt( 1, 6 );
int getNumber();
int main() {
for ( unsigned int counter = 1; counter <= 10; ++counter ) {
std::cout << std::setw( 10 ) << randomInt( engine );
if ( counter % 5 == 0 )
std::cout << std::endl;
}
std::cout << getNumber() << std::endl;
return 0;
}
int getNumber () {
return randomInt( engine );
}
Output:
/CLionProjects/Warning/cmake-build-debug/Warning
3 5 6 3 3
1 4 2 4 5
2
Process finished with exit code 0
Using global variables is problematic, and it is common wisdom to avoid them unless they're absolutely necessary. For details, see:
Your question title also regards non-global-scope static storage duration variables (e.g. static locals of functions); these are less problematic but can also give you some headaches, especially in multi-threaded work.
Bottom line: It's best to make your functions depend only on their parameters and have as few side-effects as is necessary. Let's do this with your getNumber()
function:
template <typename Distribution>
typename Distribution::result_type getNumber (
std::default_random_engine& random_engine,
Distribution& distribution)
{
return distribution( random_engine );
}
int main()
{
std::default_random_engine engine( static_cast<unsigned int>( time(nullptr) ) );
std::uniform_int_distribution<unsigned int> randomInt( 1, 6 );
for ( unsigned int counter = 1; counter <= 10; ++counter ) {
std::cout << std::setw( 10 ) << randomInt( engine );
if ( counter % 5 == 0 )
std::cout << std::endl;
}
std::cout << getNumber( engine, randomInt ) << std::endl;
return 0;
}