C++ 的 void main() / int main() … 不要再用 void main() 了!

前陣子聽說有些人學 C++ 程式設計的時候學的 main function 型態都是 “void main()” … 個人是覺得很驚訝加上有點錯愕,因為這個用法是錯的,即便在 C89 規範裡面也只有允許單純用 main(),一是省略 int,因為預設就是 int,二是沒有回傳,則狀態為 undefined,但不是可以用 void main() 啊!

微軟的 Visual C++ 支援這樣古怪的寫法很久了,在 Visual Studio 2012 (編譯器:Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1) 上面實測都還可以順利編過沒問題,但這種寫法很是不合 C/C++ 規範的,到底當初怎麼冒出來這樣的用法恐怕已經無法考證,好像 Visual C++ 6.0 就是用 void main() 來當 function prototype,但又是誰教 Visual C++ 6.0 的程式設計師這樣做的呢? 該不會是微軟為了降低程式可攜性的一種手段吧 XD

底下兩個連結很清楚的說明了 void main() 是錯誤的用法,即便是 C++ 之父也不是空口說說,同時也附上在ISO的標準裡面的相關章節,如果你的學校老師同學還在用這樣的寫法,甚至教別人這樣寫的話 … 找個機會提醒他們一下吧!

Bjarne Stroustrup’s C++ Style and Technique FAQ – Can I write “void main()”?
http://www.stroustrup.com/bs_faq2.html#void-main

The definition void main() { /* ... */ } is not and never has been C++, nor has it even been C. See the ISO C++ standard 3.6.1[2] or the ISO C standard 5.1.2.2.1. A conforming implementation accepts

void main(void) – the Wrong Thing
http://users.aber.ac.uk/auj/voidmain.cgi

  • Because the standard says so. (To which the answer is usually of the form “but it works for me!”)
  • Because the startup routines that call main could be assuming that the return value will be pushed onto the stack. If main() does not do this, then this could lead to stack corruption in the program’s exit sequence, and cause it to crash. (To which the answer is usually of the form “but it works for me!”)
  • Because you are likely to return a random value to the invokation environment. This is bad, because if someone wants to check whether your program failed, or to call your program from a makefile, then they won’t be able to guarantee that a non-zero return code implies failure. (To which the answer is usually of the form “that’s their problem”).

這邊還是補充一下另外兩篇 …

一篇是 void main() is not legal in C++ but is legal in C.、另一篇是 A proposal to correct section 5.1.2.2.1.1 of the C standard,兩篇是同一位作者,比較有趣的是兩篇的論點略有不同,甚至有一點矛盾的感覺,前面認為 void main() 在C裡面是合法的,也列舉了幾個支援 void main() 的編譯器,在後篇作者提出了自己認為 C standard section 5.1.2.2.1.1 比較好(或說比較精確?)的描述,有興趣的話可以翻翻看

小結:

void main() 不應該在 C++ 裡面出現,至於在C語言裡面仍然是有些模糊地帶。無論如何,並不是每個編譯器都支援這樣的做法,就乖乖回傳狀態,讓程式碼的可攜性好一些也是有益無害啊!