【问题标题】:C++ : how to make sure all variables are initialized?C++:如何确保所有变量都已初始化?
【发布时间】:2013-04-09 06:16:16
【问题描述】:

最近我在使用非初始化变量时遇到了很多麻烦。

在Java中,变量的默认值为null,因此如果使用未初始化的变量,很可能会抛出异常。如果我理解的话,在 C++ 中,变量会使用内存中的任何数据进行初始化。这意味着程序很可能会运行,甚至可能很难知道它有什么问题。

解决这个问题的干净方法是什么?是否有一些好的编程习惯可以降低风险?在我的例子中,变量是在头文件中声明的,并且应该在 cpp 文件中初始化,这是一个更容易出错的例子。

谢谢


收到几个答案后的版本:

抱歉,我的问题不够具体。

我得到的使用 flag 让编译器了解未初始化变量的答案会很有用。

但是有少数情况下的变量不能在一开始就被初始化,因为这取决于你系统的行为。

在头文件中

double learnedValue;

在cpp文件中

/* code that has nothing to do with learnedValue
...
*/

learnedValue = a*b*c; // values of a, b and c computed in the code above

/*code making use of learned value
...
*/

现在发生的事情是忘记了“learnedValue=a*b*c”这一行。

但是程序运行良好,只是用声明时内存中的任何内容初始化了learnedValue的值。

在 Java 中,这样的错误不是问题,因为使用学习值的代码很可能会崩溃或抛出异常(至少您知道出了什么问题)。

在 C++ 中,您显然可以很高兴,但根本不知道有问题。还是?

【问题讨论】:

  • 养成在定义时初始化变量的习惯。
  • 在 C++ 中,变量被初始化为你决定用什么来初始化它。如果您让它们不确定,您将掷骰子并抓住机会(即不确定 = 用作评估时未定义的行为)。
  • 只需将变量定义为您想要的任何值。例如,如果您声明 int,请将其设置为等于 0
  • 您可以使用编译器警告标志。例如,如果您使用 gcc。 -Wuninitialized 会警告你所有未初始化的变量。
  • 始终使用 -Wall-Wextra 构建,始终在声明时进行初始化,并在链接有错误的代码时处理痛苦:)

标签: c++ initialization declaration


【解决方案1】:

请确保在编译程序时设置了适当的警告级别。 每当使用未初始化的变量时,编译器都会发出适当的警告。

在 g++ 上,-Wall 编译器选项将显示所有警告。

在 Visual Studio 上,您可能必须使用警告级别 4。

此外,市场上有一些静态代码分析工具。 cppCheck 就是这样一款免费提供的工具。

【讨论】:

    【解决方案2】:

    您不应在标头中定义变量(仅声明它)。否则,当您在多个 .cpp 文件中包含标头时,会出现其他错误。

    在实际定义一个变量的时候,你也可以给它一个初始值(比如0)。在 C++ 中,延迟(局部)变量的定义也很常见,直到你有一个值可以分配给它们。

    在头文件中

    extern double learnedValue;
    ^^^^^^
    

    在cpp文件中

    double learnedValue = 0;
    
    /* code that has nothing to do with learnedValue
    ...
    */
    
    learnedValue = a*b*c; // values of a, b and c computed in the code above
    
    /*code making use of learned value
    ...
    */
    

    【讨论】:

      【解决方案3】:

      你可以在声明变量的地方定义它们

      【讨论】:

      • 不适用于静态或常量成员变量。其他成员变量要在构造函数中初始化。
      • @scones 那么你将如何定义一个 const 变量?
      • 在构造函数中定义了一个 const 成员变量(我在说什么)。在 .cpp 文件中定义了一个静态 const 成员变量(静态 const int 可能除外)。所有其他 const 变量都应在现场初始化。
      • @scones 所以是一个非常量非静态数据成员。 const 和非常量情况之间没有区别。此外,在 C++11 中,它们可以在声明时定义。
      • 有一点点不同,const 的东西不能再晚定义。虽然这种情况会引发对非常量成员的警告。
      【解决方案4】:

      c++11 允许你在类中初始化变量。如果编译器还没有实现,那么构造函数初始化列表就是要检查的区域。

      【讨论】:

        【解决方案5】:

        C# 可以初始化变量。但是 C++ 没有,所以当使用没有初始化的指针时,它总是抛出异常。你应该养成在类构造函数中初始化所有变量的好习惯。

        【讨论】:

        • 在 C++ 中取消引用未初始化的指针是未定义的行为。这当然不能保证抛出异常。
        猜你喜欢
        • 2016-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-09
        • 1970-01-01
        • 2012-03-23
        • 2020-08-16
        相关资源
        最近更新 更多