读取恰好具有良好价值的未初始​​化变量

时间:2018-03-19 09:09:15

标签: c++ embedded language-lawyer blackfin

我在Blackfin 533处理器上运行的一些代码中遇到了这个错误。

第一次Func()运行时,fooStruct将包含垃圾,但在下一次迭代中,getFoo()返回的旧值仍然会在fooStruct.foo中}。

FooStruct
{
    double foo;
    double bar;
};

void Func()
{
    FooStruct fooStruct;

    double bar = 123.4 / fooStruct.foo;

    fooStruct.foo = getFoo();
    fooStruct.bar = bar;
}

这意味着第一次运行时,我们正在读取未初始化的变量,这是未定义的行为。以下迭代怎么样?这仍然是未定义的行为吗?在嵌入式处理器上读取未初始化的变量时,我们可以期待看到什么样的行为?

2 个答案:

答案 0 :(得分:7)

遇到了一个未定义的行为,和所有后续语句的行为也是未定义的。

矛盾的是,未定义的之前的任何语句的行为也是未定义的。

对于行为的 sort ,要求对未定义的行为进行分类是不合逻辑的。

答案 1 :(得分:4)

是的,它是未定义的,但你观察到的行为并不一定令人惊讶;只是堆栈被重用并且重用的空间没有被初始化,并且您碰巧重用了与前一次调用完全相同的堆栈位置。所有内存都必须包含一些东西,如果你调用这个函数并且碰巧重新使用与之前调用相同的堆栈帧,它将包含最后留下的内容。

例如,如果你打电话:

Func() ;
Func() :

第二次调用fooStruct.foo没有定义,但不是不合理的,以包含第一次调用留下的值,因为当编译器将无操作时,会发生这种情况初始化变量。

但是如果你有了:

void Func2()
{
    int x = 0 ;
    int y = 0 ;
    Func() ;
}

然后叫:

Func() ;
Func2() ;

通过Func()Func2()的第二次调用几乎肯定会将本地fooStruct.foo放在堆栈中的不同地址,因为{的堆栈框架为{ {1}},因此除了巧合之外不会有相​​同的值。此外,如果序列是:

Func2

Func() ; Func2() ; Func() ; 的第三次调用可能使用与第一次相同的堆栈位置,但可能的空间已由Func()修改(由于初始化变量),您很可能不再在Func2()中观察到相同的值。

这就是未初始化的含义;你会得到正常的事情。并且因为当变量超出范围时,它通常不被修改,这样的值可以重新出现" (并不一定在同一个变量中) - 只是因为这是最简单和最有效的实现(即什么都不做)。