未定义变量和编译器优化
Undefined variable and the compiler optimization
我对未定义的变量和下面演示的代码片段有疑问:
在func_1()
之后---它将A
压入堆栈并将该内存的值设置为40,然后将A
弹出堆栈。
在func_2()
之后---它会再次将A
压入堆栈并继承之前设置的值,打印出的值为40。
void func_1()
{ int A = 40;}
void func_2()
{ int A; printf("%d/n",A);}
void main (void)
{
func_1();
func_2();
}
如果我们将func_2()
中的名字A
改成B
来测试栈的使用,并在里面放额外的代码来测试命名变量池的使用:
int A; printf("%d\n", A);
在我的电脑上,它说 B
是 40,A
是 0。
我想知道的是,如果编译器有一个命名变量池,它可以重用这些变量来帮助优化编译代码(?),那么为什么我在 A
上得到 0?
编译器什么时候使用池?
我的问题基于这张幻灯片:
http://www.slideshare.net/olvemaudal/deep-c/131-I_am_now_going_to
很可能函数 func_2();
中的变量 A
分配在与值 40
相同的堆栈位置(在 func_1()
中)。由于您尚未在 func_2()
中初始化变量,因此在这种情况下,它将使用内存中的随机值打印变量 40
(因为它从未被覆盖)。这类似于用户释放一个指针然后声称他们之后也能看到它的内容的情况,尽管他们可能会或可能不会看到该值,但该行为被认为是 undefined.不用说,您不应该依赖这种行为!
我做了一个简单的测试,证明与变量名无关:
void func_1()
{
int A = 40;
int B = 10;
printf("Memory A = %p Memory B = %p\n",&A, &B);
}
void func_2()
{ int B; printf("B = %d Memory B = %p\n",B, &B);}
void main (void)
{
func_1();
func_2();
printf("\n");
}
输出:
Memory A = 0x7fff58f86b5c Memory B = 0x7fff58f86b58
B = 40 Memory B = 0x7fff58f86b5c
如您所见,虽然 B = 10
in func_1()
in func_2()
打印值是 40
。为什么?如果检查 func_1()
中变量 A
的内存地址是 0x7fff58f86b5c
与 func_2()
.[=27= 中的变量 B
占用的内存地址相同]
幻灯片中的人物扮演一个白痴的角色,他发明了一个似乎可以解释他不理解的行为的想法。没有命名变量池。
此代码的行为未定义且不可依赖。如果它恰好在运行时运行以打印值 40,那只是实现的意外。
我对未定义的变量和下面演示的代码片段有疑问:
在func_1()
之后---它将A
压入堆栈并将该内存的值设置为40,然后将A
弹出堆栈。
在func_2()
之后---它会再次将A
压入堆栈并继承之前设置的值,打印出的值为40。
void func_1()
{ int A = 40;}
void func_2()
{ int A; printf("%d/n",A);}
void main (void)
{
func_1();
func_2();
}
如果我们将func_2()
中的名字A
改成B
来测试栈的使用,并在里面放额外的代码来测试命名变量池的使用:
int A; printf("%d\n", A);
在我的电脑上,它说 B
是 40,A
是 0。
我想知道的是,如果编译器有一个命名变量池,它可以重用这些变量来帮助优化编译代码(?),那么为什么我在 A
上得到 0?
编译器什么时候使用池?
我的问题基于这张幻灯片: http://www.slideshare.net/olvemaudal/deep-c/131-I_am_now_going_to
很可能函数 func_2();
中的变量 A
分配在与值 40
相同的堆栈位置(在 func_1()
中)。由于您尚未在 func_2()
中初始化变量,因此在这种情况下,它将使用内存中的随机值打印变量 40
(因为它从未被覆盖)。这类似于用户释放一个指针然后声称他们之后也能看到它的内容的情况,尽管他们可能会或可能不会看到该值,但该行为被认为是 undefined.不用说,您不应该依赖这种行为!
我做了一个简单的测试,证明与变量名无关:
void func_1()
{
int A = 40;
int B = 10;
printf("Memory A = %p Memory B = %p\n",&A, &B);
}
void func_2()
{ int B; printf("B = %d Memory B = %p\n",B, &B);}
void main (void)
{
func_1();
func_2();
printf("\n");
}
输出:
Memory A = 0x7fff58f86b5c Memory B = 0x7fff58f86b58
B = 40 Memory B = 0x7fff58f86b5c
如您所见,虽然 B = 10
in func_1()
in func_2()
打印值是 40
。为什么?如果检查 func_1()
中变量 A
的内存地址是 0x7fff58f86b5c
与 func_2()
.[=27= 中的变量 B
占用的内存地址相同]
幻灯片中的人物扮演一个白痴的角色,他发明了一个似乎可以解释他不理解的行为的想法。没有命名变量池。
此代码的行为未定义且不可依赖。如果它恰好在运行时运行以打印值 40,那只是实现的意外。