2009-10-07 155 views
0

當我試圖運行編譯並在一個簡單的C文件來執行這個語句:惠普這個程序的輸出是什麼?

main(){ printf("%d");} 

它是給我64和AIX上的給我804359524.

誰能告訴我什麼是這種行爲。

+0

哪種說法? – 2009-10-07 10:07:28

+1

RTFM。 [需要xtra字符] – spender 2009-10-07 10:10:53

回答

21

我假定你的意思:

int main() 
{ 
    printf("%d"); 
} 

既然如此,printf()的被讀取int從棧(由格式說明%d的方向)。既然你沒有指定一個,它只是讀取堆棧中的任何內容並使用它。因此,你看到僞隨機輸出。

相反,嘗試:

int main() 
{ 
    printf("%d", 10101); 
} 

HTH

2

代碼暴露了未定義的行爲。在其他系統上,它可能會打印「堆棧溢出」(嚴重!)。 %d告訴CRT庫你會提供一個整數,但是你沒有。

+0

我不認爲你會在代碼中遇到堆棧溢出 - 堆棧不會增長。 – Skizz 2009-10-07 10:20:10

+0

堆棧溢出的觸發器通常是對堆棧保護頁面的內存訪問。當printf()無法讀取%d整數時,可能會觸發該訪問,而是碰到守護頁。由於這不是一個寫,你不能通過添加另一個頁面來解決它。每當有任何不可修復的堆棧守衛頁面違例時,操作系統打印「堆棧溢出」是合理的;它會是99%正確的 – MSalters 2009-10-07 11:17:43

+1

我認爲在這種情況下,打印的值將是printf函數的返回地址,寄存器值或可能來自main的堆棧幀,具體取決於編譯器的實現和它正在運行的操作系統。我一直認爲'堆棧溢出'是當堆棧嘗試將數據存儲在堆棧時內存不足時,從不讀取數據時。 – Skizz 2009-10-07 12:06:53

0

我的猜測是,你編譯

main(){ printf("%d");} 

這將摘掉當前堆棧的隨機值。試試這個:

main() { 
    printf("%d", 0); 
    printf("%d"); 
} 

現在,第二printf()將始終打印0,因爲它得到了相同的堆棧的第一個電話。

[編輯]這不適用於x86 Linux與GCC 4.1.2。下面是所生成的彙編程序代碼(使用gcc -S -o t.s t.c):

movl $0, %esi 
    movl $.LC0, %edi 
    movl $0, %eax 
    call printf 
    movl $.LC0, %edi 
    movl $0, %eax 
    call printf 

正如你可以看到,第二個參數是不是壓入堆棧,但通過經由%esi(這是一個寄存器)。同一個寄存器可能在printf()中被修改,這就是它失去其價值的原因。該死的優化;)

+0

如果你得到1,我不會感到驚訝。printf返回消耗的參數的數量。該返回值可能會覆蓋堆棧。 – MSalters 2009-10-07 11:23:15

+0

我懷疑這是由於兩個原因:a)在大多數機器上,返回值是在一個寄存器中; b)如果它被傳遞到棧上,它會覆蓋格式化字符串,如果它沒有被ABI保存在不同的地方。 – 2009-10-07 11:40:16

+0

亞倫,與intel icc編譯器一起運行,給出了關於第二個printf和04204818(0和4204818) – Glen 2009-10-07 13:27:38

12

這是經典undefined behavior。編譯器不檢查你是否提供了足夠的參數來匹配你的格式化字符串。有編譯器這樣做(gcc is one),但你的不。

printf()的代碼將通過它的給定的格式化串愉快步驟,並且當它到達「%d」,它將讀出一個尺度的int參數(通常爲:從電池堆),不知道沒有參數在那裏讀取。

無論堆棧上發生什麼值,都會打印出來。

3

有些編譯器,如gcc,如果指定了足夠高的警告級別,就會遇到這種類型的常見問題。像這樣(編譯你的代碼,用-Wall - 所有的警告):

gcc -c -g -Wall -MMD -MP -MF build/Debug/Cygwin-Windows/newmain.o.d -o build/Debug/Cygwin-Windows/newmain.o newmain.c 
newmain.c: In function `main': 
newmain.c:16: warning: too few arguments for format 

這是大約998很好的理由總是與高警告級別編譯,並認真對待的警告信息之一。