測試 C、Python、Java 等 16 種程式語言的 Hello World:7 種存在 Bug?

測試 C、Python、Java 等 16 種程式語言的 Hello World:7 種存在 Bug?

譯者 | 張潔

責編 | 屠敏

Hello World 可能是最簡單的計算機入門程式。幾十年來,許多人在開始使用新的程式語言時,編寫的第一個程式通常是 Hello World。

這不起眼的入門程式沒有 Bug,對嗎?

測試 C、Python、Java 等 16 種程式語言的 Hello World:7 種存在 Bug?

圖片來自 sunfishcode 的部落格

畢竟,Hello World 程式只做一件事。怎麼會有 Bug?

萬萬沒想到,有開發者在好奇心驅動下,測試了 16 種常用的語言後,竟然在裡面檢測出了 7 種程式語言的 Hello World 帶有 Bug。

測試 C、Python、Java 等 16 種程式語言的 Hello World:7 種存在 Bug?

以 C 語言中的 Hello World 程式為例

首先,以 C 語言為例來測試。事實上,用 C 語言寫 Hello World 有很多不同的版本,如維基百科搜尋顯示的版本、《C 程式設計語言》(也簡稱 K&R)一書中的 Hello World,甚至還有從 1974 年貝爾實驗室備忘錄中引入的最古老的 C 語言 Hello World 程式。

測試 C、Python、Java 等 16 種程式語言的 Hello World:7 種存在 Bug?

圖片來自 sunfishcode 的部落格

這是 “ANSI C ”(

美國國家標準協會和國際標準化組織對 C 語言釋出的標準

)中的 Hello World 程式寫法:

/* Hello World in C, Ansi-style */

#

include

#

include

int

main

void

{

puts

“Hello World!”

);

return

EXIT_SUCCESS;

}

對於業界而言,這應該是最標準 C 語言 Hello World 的版本。

它使用“(void)”來顯示 main 是一種新型宣告方式。這個版本使用 EXIT_SUCCESS 返回值來表示成功,而不是使用 0。根據 C 語言標準,這其實沒有必要,不過在此我們也不做更改了。除此之外,它還使用了適當的標頭檔案聲明瞭 puts 函式。

這個版本試圖把所有的步驟都做到完美。

然而,它裡面還是有一個 Bug。

測試 C、Python、Java 等 16 種程式語言的 Hello World:7 種存在 Bug?

C 語言中的 Bug 從何而來?

Linux 有一個有趣的裝置檔案,叫做“/dev/full”,跟“/dev/null”(

程式設計師群體中行話叫做黑洞,即丟棄一切寫入其中的資料,讀取它會立即得到一個 EOF

)非常像,但是當你將資料寫入到“/dev/full”時,該檔案不會扔掉資料,而會出現錯誤。它的作用就像是檔案系統中一個剛剛用完空間的檔案:

$

echo

“Hello World!”

> /dev/full

bash: echo: write error: No space left on device

$

echo

$?

1

因此用這個檔案可以用來測試程式是否正確處理 I/O 錯誤。建立沒有剩餘空間的實際檔案系統或實際發生故障的磁碟很不方便,但要求程式將其輸出寫入“/dev/full”檔案中,看看會發生什麼吧。

所以讓我們測試一下上面的 C 語言示例:

$ gcc hello。c -o hello

$ 。/hello >

/dev/full

$ echo $?

0

與我們在上面的 shell 指令碼中使用 echo 時不同,在這裡,我們沒有得到任何輸出的內容,返回值為 0。這意味著 Hello World 程式執行成功了。

然而,它實際上並沒有成功。我們可以使用 strace 進行確認:

$ strace -etrace=write 。/hello >

/dev/

full

write(

1

“Hello World!\n”

13

) =

-1

ENOSPC (No space left on device)

+++ exited

with

0

+++

作業系統提示了 “No space”錯誤。但是,程式還是成功執行了,並返回值為 0,這以為系統認為這一段程式碼是成功的。

顯而易

見,這是一個 B

ug!

那麼,這個 Bug 有多嚴重呢?

,Hello World 不應該作為標準的測試程式碼,因為它並不是

對的安全

此話應該從何說起?想必很多程式設計師在初次學習程式設計的時候,大多數會用 Hello World 程式來試一下。這也導致了 Hello World 常被開發者用來檢測程式的標準輸出,但是因為此時 Hello World 程式存在 Bug,所以 prints 的標準輸出往往可能會被重定向到另一個檔案。

譬如,現實世界中,

如果檔案佔用了全部的空間。此時用 Hello World 程式來檢測,最終並沒有檢測任何問題

,那麼該程式碼的父程序將不知道子程序失敗了,會繼續執行,即使系統期望產生的輸出內容已經悄悄地丟失了資料,但程式還是像什麼都沒有發生一樣。

舉個例子,編寫一個程式,其中主要是

prints

一個 yaml 檔案到標準輸出。如果標準輸出的空間用完了,輸出可能會在某個任意的點被截斷,儘管它仍是有效的 yaml。所以我們期望程式能夠檢測並報告這種情況。

測試 C、Python、Java 等 16 種程式語言的 Hello World:7 種存在 Bug?

7 種主流語言常見的 Hello World 程式都有 Bug?

除了 C 語言之外,Python 告訴我們“Bug 不應該被無聲地忽視”,下面是 Python 2 的測試示例:

$ python2 hello。py >

/dev/full

close failed

in

file object

destructor:

sys。excepthook is missing

lost sys。stderr

$ echo $?

0

它確實向 stderr 輸出了一條資訊,並且還是一條令人困惑的資訊。然而,它也返回了 0,這意味著它在告訴執行它的人,它成功退出了。

幸運的是,Python 3 正確地報告了錯誤,而且還顯示了一個更漂亮的錯誤資訊。

$ python3 hello。py >

/dev/full

Exception ignored

in:

<_io。TextIOWrapper name=

mode=

‘w’

encoding=

‘utf-8’

>

OSError:

[Errno

28

] No space left on device

$ echo $?

120

另外,我也還是使用普通教程網站上的 Hello World 程式,嘗試了其他幾種程式語言,以下是測試結果:

測試 C、Python、Java 等 16 種程式語言的 Hello World:7 種存在 Bug?

原文連結:

https://blog。sunfishcode。online/bugs-in-hello-world/

宣告:本文為 CSDN 翻譯,轉載請註明來源。

END

《新程式設計師001-004》全面上市,對話世界級大師,報道中國IT行業創新創造

測試 C、Python、Java 等 16 種程式語言的 Hello World:7 種存在 Bug?

測試 C、Python、Java 等 16 種程式語言的 Hello World:7 種存在 Bug?

測試 C、Python、Java 等 16 種程式語言的 Hello World:7 種存在 Bug?

測試 C、Python、Java 等 16 種程式語言的 Hello World:7 種存在 Bug?