2012-05-21 84 views
0

this presentation的幻燈片137-140中,有人提到bar()甚至foo()被編譯爲本示例程序的內聯函數,導致打印輸出爲42在正常生產中,即使它在技術上應該是垃圾。你碰巧知道爲什麼當優化器啓動時輸出的垃圾如預期的那樣?正常和優化版本之間的正確返回值

我已經包含的源代碼

#include <stdio.h> 
void foo(void) 
{ 
    int a; 
    printf("%d\n", a); 
} 
void bar(void) 
{ 
    int a = 42; 
} 
int main(void) 
{ 
    bar(); 
    foo(); 
    return 0; 
} 

和用於參考的命令提示打印輸出。

$ cc foo.c && ./a.out 
42 

$ cc -O foo.c && ./a.out 
1606415608 

在此先感謝您的解釋。

+0

bar()將var a放在堆上。由於var只是本地的,所以從堆中刪除。之後,foo()在堆上使用相同的地址。因此42仍在那裏。希望我沒有犯任何重大錯誤,但我認爲我是正確的。 – cen

+0

@cen:所以實際上,var a不是放在棧上,而是放在堆上? – stanigator

+0

它應該在堆棧上。局部變量始終在堆棧上。 – nhahtdh

回答

2

只是一個受過教育的猜測:

在非優化情況下,編譯保留的空間用於在杆()的變量,並把它初始化爲42。然後,當FOO()被調用時,它使用相同的空間用於未初始化的a並打印出來42.

優化後,bar()中的初始化會被優化掉,因爲它沒有被使用。可能吧,即使打電話給bar()也被取消了。所以,正如所料,foo()會打印出垃圾,也就是當時在那個內存插槽(或寄存器)中發生的任何事情。

0

a在第一個函數中未初始化,這意味着您不能指望它具有任何特定的值。所以編譯器的行爲在兩種情況下都是正確的(你沒有優化就得到42個只是巧合)。