邪惡的程式設計咒語

精算狗發表於2018-03-12

自從我看了 Gary Bernhardt 備受推崇的一個視訊 Wat,就驚異於特定程式語言的怪異行為。相較於其他程式語言來說,某些程式語言的行為更出乎意料。例如,有一整本書是針對 Java 的邊緣案例和古怪情況。同樣,差不多隻要 200 美元你就可以閱讀 C++ 規範說明了。

邪惡的程式設計咒語

下面是我最喜歡的、驚奇的、滑稽的並仍然有效的咒語集合。一般來講,利用這些古怪的行為被視為壞事,因為程式碼不應該出乎意料。值得慶幸的是,如果你嘗試以下大多數蠢事,有很多程式碼校檢工具(linters)已經準備好嘲笑你了。說了這麼多,知識就是力量,那就開始吧。

Python 2 中對 True 邪惡的重賦值

謝天謝地,這在 Python 3 中會導致 SyntaxError,因為 True、False 和 None 現在是保留字。它仍遠沒有 C++ 的那個惡作劇那麼邪惡,把 #define true false 悄悄寫進同事的開發機器的標準標頭檔案中。

Java 和 Python 中的詭異行為例項

對 Java 新手程式設計師來說,== 的語義往往使人困惑。甚至在微不足道的情境下,這個操作符的前後矛盾也會使情況變得複雜,即使效能效益是值得的。

JVM 會對區間 [-128, 127] 內的值使用相同的引用。更奇怪的是,Python 中也有同樣的行為。

目前為止,還沒有特別出乎意料的。

似乎 python 直譯器使用相同例子的下限是……-5。區間 [-5, 256] 內的整數有同樣的 ID。不知怎地,這變得更奇怪了。

似乎使用解構賦值改變了這裡的規則。我不確定為什麼是這樣。事實上,我在 Stack Overflow 上提了一個問題來試著理解它。我的猜測是,一個列表中的重複值指向同一個物件,用以節省記憶體。

C 中顛倒的下標符號

顛倒的下標符號,會使所有開發者都頭疼。

這行得通的原因是,array[index] 確實只是 *(array + index) 的語法糖。由於加法的交換性,我們可以交換陣列和索引,並得到同樣的結果。

C 中的“倒數”操作符

–> 操作符第一次被看到時,似乎是句法錯誤。在你意識到它可編譯時,它看起來像未被記載的語言特性。幸運的是,兩者都不是。

–> “操作符”實際上是兩個操作符,在這個背景下解析為 (x–) > 0。眾所周知,大量使用會導致困惑,這完全是邪惡的。

C 中的 sizeof 操作符

sizeof 操作符是一個編譯時操作符,這給予了它有趣的屬性。

由於 sizeof 操作符的例子是對編譯時進行評估的,(x += 1) 不會執行。另一件趣事是,研究表明 printf(“wtf?”) 是最普遍的沒有被 push 的程式碼。

Lua、Smalltalk、MATLAB 及其他語言,索引由 1 開始

/r/programminghumor 一直在用“indexing starts at 1”表情包取樂。令人震驚的是,有大量程式語言使用從 1 開始的陣列索引。可以在這裡找到更全面的清單。

Ruby 中的 0 被判為 true

… and only Ruby. *

在 Ruby 中是這樣。*

* edit: It was pointed out on reddit that this is true for Lua, Lisp, and Erlang as well.

* 修訂:Reddit 上有人指出,這在 Lua、Lisp 和 Erlang 中也成立。

Trigraph, Digraphs, and Tokens in C

C 中的 Trigraph、Digraph 和 Token

由於歷史原因,C 語言中的非字母符號有替代品。

邪惡的程式設計咒語

有些外國裝置,例如 IBM 3270,在 C/C++ 中不提供某些常用符號,所以提供了 digraph、trigraph 和 token 來避免排斥特定字符集。

相關文章