2012-12-18 48 views
0

之前有人可能會標記它相關的問題重複。我強調我DO已閱讀所有這些問題。但我仍然有一些審訊(是的,一些小的迂腐:))如果我省略C中主函數的返回類型,該怎麼辦?

對於C

一些結論:

1. In C89(C90), this is _undefined_ . 
2. In C99(or C11), a type of int is madatory; control flow reached the closing } 
    will return a value of 0. 

這纔是我的審訊。

  1. c89,我都一無所知不確定,但不明發現了什麼?

    詳細信息:C89相關部分是5.1.2.2.1計劃啓動5.1.2.2.3計劃終止注意:兩者都是5.1.2.2託管環境下部分,在其中我們後面的討論是limitted)

    引用: - 5.1.2.2.3計劃終止 -

    A return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument.10 If the } that terminates the main function is reached, the termination status returned to the host environment is unspecified.

    不過請注意部分:如果}終止...,上面清清楚楚地寫着 ,如果我們忽略了返回類型 - 因此}將達到 -
    終止狀態不明

    根據的不確定不明標準的定義, 我應該說,它給未指定的值,因爲不管它返回的是合法的int值,但因此不確定 - 我們無法預測哪個值會導致什麼樣的災難性後果?

  2. 在C99中,一個int類型是madatory,但gcc --std=c99給出,但int型測試(沒有返回類型實際上)僅給出華林:的「主」的返回類型不是「詮釋」,但不錯誤

    詳細說明:相關部件與c89相同。

    引用: - 5.1.2.2.1計劃啓動 -

    It shall be defined with a return type of int and ...

    和 - 4。 - 符合

    1. In this International Standard, ‘‘shall’’ is to be interpreted as a requirement on an implementation or on a program; conversely, ‘‘shall not’’ is to be interpreted as a prohibition.

    所以應該在這個標準解釋爲madatory,爲什麼GCC與開關等--std = C99違反本?

+0

向gcc維護者報告bug。 –

+2

使用'-pedantic-errors'使GCC中的ISO違規錯誤 – Cubbi

+0

'gcc -std = c99'只是一個寬鬆的近似值,它仍然吞噬了大部分被刪除的c89內容和擴展。但是,它提供了一個診斷,而不是必需的。如果你想要一個很好的近似標準,也可以使用'-pedantic-errors'。 –

回答

3

C89/90仍具有隱式int類型的規則,所以main()相當於int main()。通過關閉返回類型,您已隱式地將返回類型定義爲int。有些人可能會認爲這是馬虎,但它嚴格符合(即不涉及實現定義,未定義或未指定的行爲)。

對於C99,隱含的int規則已被刪除,因此main()未定義。 但是,編譯器僅在遇到違反ShallShall not子句時才被要求「發佈診斷」 - 在發佈診斷之後仍然可以繼續編譯。確切地說,構成診斷的是實施定義。因此,gcc在這方面需要符合的所有內容都是文檔來說明它發佈的警告是被視爲診斷。

編輯:「隱int」在C89/90標準是不是真的在一個地方一個規則 - 它在幾個地方周圍蔓延。主要的一個是§6.5.2.1,在那裏說:

- intsignedsigned int,或沒有類型說明符

這是一個列表的一部分,這裏所有的每一個項目列表中的行被認爲是等同的,所以這是說(除非另外禁止)缺少類型說明符相當於指定(簽名)int

對於函數參數,有一個單獨的規範(在第6.7.1節):「沒有聲明的任何參數的類型爲int」。

+0

[C89/90仍然有隱式int規則]請問您能否給我標準引用請? – larmbr

+0

@larmbr:見編輯答案[我討厭打印在紙上的標準]。 –

+0

謝謝-_- || ... – larmbr

0

即使在違反約束的情況下,C編譯器必須發出的唯一事情就是「診斷」。然後允許它繼續並生成可執行程序。

+0

謝謝。我使用-pedantic-erros開關,然後它會抱怨錯誤 – larmbr

0

不過請注意部分:如果}終止 ...,它清楚地說,如果我們忽略了返回類型

不,不。它說明當您從main()末尾省略return exitStatus;會發生什麼情況。

據** **未定義和未特指的標準的定義,我應該說,它給了,因爲不管它返回是一個合法的int值未指定的值,但consequese是不確定的,我們不能預測什麼價值將導致災難性的後果。

不,這意味着你不知道你的程序的返回狀態碼是什麼。但是,這種行爲並沒有定義:程序終止。用什麼樣的結果代碼,這是一個不同的問題。

[...]只給waring:'main'的返回類型不是'int',但不是錯誤?

這就是它的實現。在舊C(C89)中 - 以及一些較新的編譯器 - 如果您省略函數的返回類型,則假定爲int(因此即使警告看起來有點問題)。

所以在這個標準中應該被解釋爲madatory,爲什麼gcc用swith --std = c99違反了這個標準?

可能是的。請注意,除非您使用-ansi -pedantic,否則GCC是不符合要求的實現,因此從理論上講,沒有這些標誌編譯的任何程序都有未定義的行爲。但這就是理論...

+0

是的,但如果一個主沒有返回類型,那麼}將達到,這仍然是標準的解釋,是不是(當然,你的可能是原來的意思) – larmbr

+0

@larmbr'main()'沒有返回類型,也沒有'return 0;'語句在最後沒有任何關係。你可以做他們兩個,或者只是其中一個,或者兩個都不是(最優的)。你誤解了標準的措詞。 – 2012-12-18 14:54:45

+0

而downvote的原因是: – 2012-12-18 16:30:36

0

這似乎是某種C90標準參考錯誤。我不知道您鏈接的文檔是否與實際的ISO C90標準相同。

顯然,這個特定的問題已經從未定義,變爲未指定,變成了多年來的明確定義。

在ANSI-C的早期草案 「爲X3.J11工作組」,你會發現下面的文字:

2.1.2.2託管環境

「計劃終止」

從初始調用返回主函數相當於 以主函數 函數返回的值爲參數調用exit函數。如果主函數執行 指定沒有值的返回,則返回到主機 環境的終止狀態爲undefined

+0

相當好的提示,謝謝。至於引用的C89標準,這只是一個草案,也許它不是最終的印刷品,但我找不到它。 – larmbr

+0

@larmbr其實你發佈的鏈接看起來更像是某種後C90草案,因爲它列出了1993年的規範標準。 – Lundin

相關問題