【问题标题】:Uninitialized variable - passing it to a function未初始化的变量 - 将其传递给函数
【发布时间】:2023-03-06 08:08:01
【问题描述】:

http://en.cppreference.com/w/cpp/language/storage_duration

静态局部变量

在块范围内声明的静态变量首先被初始化 时间控制通过他们的声明(除非他们的 初始化是零初始化或常量初始化,可以是 在第一次进入块之前执行)。在所有进一步的电话中, 声明被跳过。

这句话中的“静态”是什么意思?是吗:

静态存储持续时间。对象的存储空间是在什么时候分配的 程序开始并在程序结束时释放。

如果是这样,那么它不会解释 int k;main 或任何其他函数中在初始化方面会发生什么,因为 k 不是静态变量(当程序开始并在程序结束时释放 - 稍等一下,您可能会说main 函数在程序开始时开始运行并在程序结束时返回,但我猜它不是这样工作的。

在主函数中:

int k;
k++;

导致错误:uninitialized local variable 'k' used

那么如果上面的k不是一个静态局部变量,你能举一个这样的变量的例子吗?

谁能告诉我为什么即使k 没有初始化,下面的代码编译和运行也没有问题?

给定一个没有主体的函数:

void foo(int* number) { }

main 中这样称呼它:

int k;    
foo(&k);
k++;

现在编译和运行没有问题,但是k 的值是-858993459。编译器不喜欢我试图在没有启动的情况下递增它的事实,但是将它传递给foo 导致编译器忘记了它。为什么?

【问题讨论】:

  • 反对者,请解释原因?
  • 一个程序在main 被调用之前开始,在main 返回之后结束。局部变量有自动存储时长,除非你用static指定静态时长,比如static int k;

标签: c++ initializer


【解决方案1】:

可能取决于您的编译器实现。 我猜编译器会看到您的变量以非常量方式传递给函数,因此该函数可能会修改/初始化 k 的值。 您的编译器不会深入挖掘函数来推断逻辑,因此它可以让您编译代码。

编辑:我没有得到与此在线编译器相同的行为:http://cpp.sh/9axqz 但是,只要我对函数中的数字进行操作,编译警告就会消失。

【讨论】:

  • 在 Visual Studio 中,我没有收到警告,而是出现编译错误。将其传递给 foo 后,它就消失了。
【解决方案2】:

静态局部变量是这样的:

void example() {
  static int i = 0; // a static local variable
  int j = 0; // not static
  // ...
}

int 等内置类型不会自动初始化。因此,当您在将其设置为有意义的值之前尝试读取该变量时,可能会收到警告,因为它几乎可以容纳任何东西。

仅仅因为您的特定编译器不再给您警告并不意味着您的变量已正确初始化。根据经验,您应该始终明确地初始化您的变量,以避免在没有先设置的情况下意外读取它:

int i; // not initialized
int j = 0; // explicitly set to 0

这里是关于初始化主题的 C++ 核心指南的链接:https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es20-always-initialize-an-object,可能值得一读。

【讨论】:

  • 我对那篇文章中静态的含义感到困惑。不知何故,我认为他们在那里使用了不同含义的静态变量,尤其是在前面的段落中已经解释了静态存储......
【解决方案3】:

静态变量可以这样定义:

int nextIndex()
{
    static int index = -1;
    return ++index;
}

所以当你第一次调用这个函数时,静态变量index 将被初始化为-1;。下一行将index 增加1 并返回结果。

nextIndex 的所有后续调用将只执行return ++index; 部分并跳过初始化。

如果没有不同的实现,静态变量也会自动初始化为零。

所以如果你把上面的函数改成

int nextIndex()
{
    static int index;
    return ++index;
}

它返回的第一个值将是一个。此外,第一次调用不会初始化index,但它会在您的程序启动后立即初始化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多