社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

测试 C、Python、Java 等 16 种编程语言的 Hello World:7 种存在 Bug?

程序人生 • 3 年前 • 246 次点击  

译者 | 张洁

责编 | 屠敏

出品 | 程序人生 (ID:coder _life)

Hello World 可能是最常用的计算机程序。几十年来,许多人在开始使用新的编程语言时,编写的第一个程序通常是 Hello World 。

这不起眼的入门程序没有 bug,对吗?

图片来自 sunfishcode 的博客

毕竟,Hello World 程序只做一件事。怎么会有 Bug?

万万没想到,有开发者在好奇心驱动下,测试了 16 种常用的语言后,竟然在里面检测出了 7 种编程语言的 Hello World 带有 Bug。

 

以 C 语言中的 Hello World 程序为例  


首先,以 C 语言为例来测试。事实上,用 C 语言写 Hello World 有很多不同的版本,如维基百科搜索显示的版本、《C 程序设计语言》(也简称 K&R)一书中的 Hello World,甚至还有从 1974 年贝尔实验室备忘录中引入的最古老的 C 语言 Hello World 程序。

图片来自 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 语言中的 Bug 从何而来?


Linux 有一个有趣的设备文件,叫做“/dev/full”,跟“/dev/null”(程序员群体中行话叫做黑洞,即丢弃一切写入其中的数据,读取它会立即得到一个 EOF)非常像,但是当你将数据写入到“/dev/full”时,该文件不会扔掉数据,而会出现错误。它的作用就像是文件系统中一个刚刚用完空间的文件:

$ echo "Hello World!" > /dev/fullbash: 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/fullwrite(1, "Hello World!\n", 13) = -1 ENOSPC (No space left on device)+++ exited with 0 +++

操作系统提示了 "No space"错误。但是,程序还是成功执行了,并返回值为 0,这以为系统认为这一段代码是成功的。显而易见,这是一个 Bug!

那么,这个 Bug 有多严重呢?

可以说,Hello World 不应该作为标准的测试代码,因为它并不是绝对的安全。

此话应该从何说起?想必很多程序员在初次学习编程的时候,大多数会用 Hello World 程序来试一下。这也导致了 Hello World 常被开发者用来检测程序的标准输出,但是因为此时 Hello World 程序存在 Bug,所以 prints 的标准输出往往可能会被重定向到另一个文件。

譬如,现实世界中,如果文件占用了全部的空间。此时用 Hello World 程序来检测,最终并没有检测任何问题,那么该代码的父进程将不知道子进程失败了,会继续运行,即使系统期望产生的输出内容已经悄悄地丢失了数据,但程序还是像什么都没有发生一样。

举个例子,编写一个程序,其中主要是 prints 一个 yaml 文件到标准输出。如果标准输出的空间用完了,输出可能会在某个任意的点被截断,尽管它仍是有效的 yaml。所以我们期望程序能够检测并报告这种情况。

 

7 种主流语言常见的 Hello World 程序都有 Bug?


除了 C 语言之外,Python 告诉我们“Bug 不应该被无声地忽视”,下面是 Python 2 的测试示例:

$ python2 hello.py > /dev/fullclose failed in file object destructor:sys.excepthook is missinglost sys.stderr$ echo $?0

它确实向 stderr 输出了一条信息,并且还是一条令人困惑的信息。然而,它也返回了 0,这意味着它在告诉运行它的人,它成功退出了。

幸运的是,Python 3 正确地报告了错误,而且还显示了一个更漂亮的错误信息。

$ python3 hello.py > /dev/fullException ignored in: <_io.textiowrapper name="<span" class="code-snippet__string">'' mode='w' encoding='utf-8'>OSError: [Errno 28] No space left on device$ echo $?120

另外,我也还是使用普通教程网站上的 Hello World 程序,尝试了其他几种编程语言,以下是测试结果:

语言

是否有bug

测试的版本

C

(全部)

C++

(全部)

Python 2

 是

Python 2.7.18

Ruby

ruby 2.7.2p137(2020-10-01 修订版 5445e04352)[x86_64-linux-gnu]

Java

openjdk 11.0.11 2021-04-20

Node.js

v12.21.0

Haskell

Glorious Glasgow Haskell 编译系统,版本 8.8.4

Rust

rustc 1.59.0 (9d1b2106e 2022-02-23)

Python 3

Python 3.9.5

Perl

perl 5,版本 32,subversion 1 (v5.32.1) 为 x86_64-linux-gnu-thread-multi 构建(带有 46 个注册补丁...)

Perl 6

v2020.12

Bash

GNU bash,版本 5.1.4(1)-release (x86_64-pc-linux-gnu)

Awk

GNU Awk 5.1.0, API: 3.0 (GNU MPFR 4.1.0, GNU MP 6.2.1)

OCaml

4.08.1

Tcl

8.6.11

C#

Mono JIT 编译器版本 6.8.0.105

原文链接:https://blog.sunfishcode.online/bugs-in-hello-world/

声明:本文为 CSDN 翻译,转载请注明来源。

《新程序员001-003》全面上市,对话世界级大师,报道中国IT行业创新创造!

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/129578