2012-12-18 45 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

相关问题