我在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;
}
这意味着第一次运行时,我们正在读取未初始化的变量,这是未定义的行为。以下迭代怎么样?这仍然是未定义的行为吗?在嵌入式处理器上读取未初始化的变量时,我们可以期待看到什么样的行为?
答案 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()
中观察到相同的值。
这就是未初始化的含义;你会得到正常的事情。并且因为当变量超出范围时,它通常不被修改,这样的值可以重新出现" (并不一定在同一个变量中) - 只是因为这是最简单和最有效的实现(即什么都不做)。