如何处理静态存储持续时间警告?

Tim*_* B. 7 c++ global-variables c++11

我是一个试图从书中学习C++的新手.下面的代码工作和预期产生输出,但也有定义两行警告enginerandomInt"具有静态存储时间'引擎’的初始化可能会引发无法捕获的异常."

如果我把线7和8的内部main(),警告完全消失,但随后enginerandomInt没有提供给getNumber.

我不知道如何修复警告.另外,也许更重要的是,randomInt在各个地方使用的正确方法是什么main()?声明它main()然后根据需要将它传递给函数是否合适?不知怎的main(),感觉不适合宣布这些类型的东西.

我之前问了一个与此类似的问题,但我仍然在努力理解,并提供了一个希望有用的例子.

// 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 );
}
Run Code Online (Sandbox Code Playgroud)

输出:

/CLionProjects/Warning/cmake-build-debug/Warning
         3         5         6         3         3
         1         4         2         4         5
2

Process finished with exit code 0
Run Code Online (Sandbox Code Playgroud)

R S*_*ahu 10

推迟全局变量初始化的一种方法是将它们包含在get函数中.

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;
}
Run Code Online (Sandbox Code Playgroud)

然后使用getEngine()getRandomInt()不是直接使用变量.

  • 这被认为是一个好的做法吗?对我来说,这只会让代码变得更复杂 (6认同)
  • @Patrick 不, std::default_random_engine 被声明为静态,因此只会在第一次调用时初始化。 (5认同)
  • 这很好,因为错误发生在函数调用时,初始化中的异常将传播到调用者,而不是在模块加载时。只需将全局包装在具有静态成员的函数中...并返回它。 (2认同)

ein*_*ica 7

使用全局变量是有问题的,除非绝对必要,否则避免使用它们是常识。有关详细信息,请参阅:

全局变量不好吗?

您的问题标题还涉及非全局范围的静态存储持续时间变量(例如函数的静态局部变量);这些问题较少,但也会让您头疼,尤其是在多线程工作中。

底线:最好让你的函数只依赖于它们的参数,并且尽可能少地产生必要的副作用。让我们用你的getNumber()函数来做这件事:

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;
}
Run Code Online (Sandbox Code Playgroud)

  • `std::string`(通常)在堆上分配空间。对于常量字符串,您不需要它。使用 `std::string_view` 并将其设置为 constexpr;你不应该收到任何警告。 (2认同)
  • @EdwardFalk,如果您不能使用 string_view,请使用旧的 `char const* const = “text”;` (或 constexpr)。没有什么问题。 (2认同)