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
The static storage duration means that the variable will last for the entire execution time of the program. This means that a static variable will stay valid in the memory till the program is running.
A local variable declared at block scope normally has an automatic storage duration. Local variables are stored in a run-time stack.
The auto storage class is the default for variables declared inside a block. A variable x that has automatic storage is deleted when the block in which x was declared exits. You can only apply the auto storage class specifier to names of variables declared in a block or to names of function parameters.
Auto, extern, register, static are the four different storage classes in a C program. A storage class specifier in C language is used to define variables, functions, and parameters. auto is used for a local variable defined within a block or function.
One way to defer initialization of global variables such as the ones you are using is to wrap them in get-functions.
std::default_random_engine& getEngine() { // Initialized upon first call to the function. static std::default_random_engine engine(static_cast<unsigned int>(time(nullptr))); return engine; } std::uniform_int_distribution<unsigned int>& getRandomInt() { // Initialized upon first call to the function. static std::uniform_int_distribution<unsigned int> randomInt(1, 6); return randomInt; } and then use getEngine() and getRandomInt() instead of using the variables directly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With