为int的main(){}(不含"无效")有效和便携式在ISO C? [英] Is int main() { } (without "void") valid and portable in ISO C?
问题描述
C标准规定两种形式定义为主
的
托管实现:
The C standard specifies two forms of definition for main
for a
hosted implementation:
int main(void) { /* ... */ }
和
int main(int argc, char *argv[]) { /* ... */ }
有可能的方式被定义为等效上述(为
例如,您可以更改参数的名称,由一个typedef替换 INT
名称定义为 INT
,或写的char * argv的[]
为的char ** argv的
)。
It may be defined in ways that are "equivalent" to the above (for
example, you can change the parameter names, replace int
by a typedef
name defined as int
, or write char *argv[]
as char **argv
).
它也可以定义为在其他一些实现定义方式
- 这意味着,之类的东西 INT主(INT ARGC,CHAR *的argv [],
是有效的如果的实施文件他们。
字符* envp)
It may also be defined "in some other implementation-defined manner"
-- which means that things like int main(int argc, char *argv[],
char *envp)
are valid if the implementation documents them.
在在其他一些实现定义的方式的条款是不是在
1989/1990标准;它是由1999标准中加入(但
较早标准允许的扩展,因此实现可能
仍然允许其他形式)。
The "in some other implementation-defined manner" clause was not in the 1989/1990 standard; it was added by the 1999 standard (but the earlier standard permitted extensions, so an implementation could still permit other forms).
我的问题是:鉴于目前(2011年),ISO C标准,一个是
形式定义
My question is this: Given the current (2011) ISO C standard, is a definition of the form
int main() { /* ... */ }
对于所有托管实现有效和便携式?
valid and portable for all hosted implementations?
(请注意,我不是针对任何无效的主要
或使用 INT的main()
没有在C ++中括号。这仅仅是对
区分 INT主要(无效)
和 INT的main()
在ISO C)
(Note that I am not addressing either void main
or the use of
int main()
without parentheses in C++. This is just about the
distinction between int main(void)
and int main()
in ISO C.)
推荐答案
没有。
根据标准的规范写法,定义
使用空括号,而不无效
关键字不是一
必须接受的形式,并且严格地说的行为
这样的程序是不确定的。
According to the normative wording of the standard, a definition
using empty parentheses without the void
keyword is not one of the
forms that must be accepted, and strictly speaking the behavior of
such a program is undefined.
参考:
N1570
部分5.1.2.2.1。 (公布的2011 ISO C标准,这是不
免费提供的,具有同样的措辞为N1570草案)。
Reference: N1570 section 5.1.2.2.1. (The published 2011 ISO C standard, which is not freely available, has the same wording as the N1570 draft.)
第1款说:
称为在程序启动时的功能被命名为 主
。实施没有声明
原型此功能。它应符合 INT
并没有返回类型定义
参数:
The function called at program startup is named
main
. The implementation declares no prototype for this function. It shall be defined with a return type ofint
and with no parameters:
int main(void) { /* ... */ }
或两个参数(这里称为 ARGC
和 的argv
,虽然任何名称可能是
使用,因为它们是局部的,其中声明它们的功能):
or with two parameters (referred to here as argc
and argv
, though any names may be
used, as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
或同等学历;或在一些其它实现定义方式。
or equivalent; or in some other implementation-defined manner.
在使用这个词的应当之外的约束意味着任何
程序违反其不确定的行为。所以,如果,例如,我写的:
The use of the word "shall" outside a constraint means that any program that violates it has undefined behavior. So if, for example, I write:
double main(unsigned long ocelots) { return ocelots / 3.14159; }
一保形编译不需要打印诊断,但它是
也不需要任何编译程序,或者,如果它不编译
它,有它在任何特定的方式行事。
a conforming compiler isn't required to print a diagnostic, but it's also not required either to compile the program or, if it does compile it, to have it behave in any particular manner.
如果 INT的main()
是相当于到 INT主要(无效)
,那么它
将是有效的,并移植到任何符合托管的实现。
但它是不等价的。
If int main()
were equivalent to int main(void)
, then it
would be valid and portable to any conforming hosted implementation.
But it's not equivalent.
int main(void) { }
既提供的声明的(在这种情况下,原型)和一个
的定义的。该声明,通过无效
关键字,指定函数没有参数。该定义规定了同样的事情。
provides both a declaration (in this case, a prototype) and a
definition. The declaration, by using the void
keyword, specifies that the function has no parameters. The definition specifies the same thing.
如果我不是写:
int main() { }
然后我使用的旧式的声明和定义。 (这样
声明和定义的过时的,但他们仍然
所有标准的编译器的语言定义的一部分,绝
仍然支持他们。)
then I'm using an old-style declaration and definition. (Such declarations and definitions are obsolescent, but they're still part of the language definition, and all conforming compilers must still support them.)
作为一个声明,它不指定(S)参数的数量或类型
函数预期。作为一个定义,它定义了没有参数,
但是编译器不需要使用这些信息来诊断不正确的电话。
As a declaration, it doesn't specify the number or type(s) of arguments expected by the function. As a definition, it defines no parameters, but compilers needn't use that information to diagnose incorrect calls.
DR#317 包括C标准委员会2006年的裁决,有一个定义()
不提供相当于一个原型(无效)
(感谢HVD的发现参考)。
DR #317 includes the C standard committee's 2006 ruling that a definition with ()
does not provide a prototype equivalent to one with (void)
(thanks to hvd for finding that reference).
C允许主
递归调用。假设我写的:
C allows main
to be called recursively. Suppose I write:
int main(void) {
if (0) {
main(42);
}
}
可见原型 INT主要(无效)
指定主
需要
没有参数。试图调用传递一个或多个参数
违反了约束,要求编译时诊断。
The visible prototype int main(void)
specifies that main
takes
no arguments. A call that attempts to pass one or more arguments
violates a constraint, requiring a compile-time diagnostic.
或者假设我写的:
int main() {
if (0) {
main(42);
}
}
如果调用主(42)
被执行,这将有不确定的操作
- 但它不违反约束,并没有诊断是必需的。
由于它是由保护,如果(0)
,呼叫从未发生,并
实际上从未发生不确定的行为。如果我们假设 INT的main()
是有效的,那么这个程序必须由接受任何
符合编译器。但正因为如此,它表明, INT的main()
是的不的等同于 INT主要(无效)
,并因此
不受5.1.2.2.1覆盖
If the call main(42)
were executed, it would have undefined behavior
-- but it doesn't violate a constraint, and no diagnostic is required.
Since it's protected by if (0)
, the call never happens, and
the undefined behavior never actually occurs. If we assume that
int main()
is valid, then this program must be accepted by any
conforming compiler. But because of that, it demonstrates that
int main()
is not equivalent to int main(void)
, and therefore
is not covered by 5.1.2.2.1.
结论:继的标准写法,一种
实施允许文件证明 INT的main(){}
是
允许的。如果没有记录它,它仍然允许接受
它毫无怨言。但是,符合编译器还可以拒绝的 INT的main(){}
,因为它不是由许可的形式之一
标准的,其行为是不确定的,因此
Conclusion: Following the wording of the standard, an
implementation is permitted to document that int main() { }
is
permitted. If it doesn't document it, it's still permitted to accept
it without complaint. But a conforming compiler may also reject
int main() { }
, because it is not one of the forms permitted by
the standard, and its behavior is therefore undefined.
但仍然有一个悬而未决的问题:是作者的意图
标准的?
But there's still an open question: Was that the intent of the authors of the standard?
在此之前的1989年的ANSI C标准的出版,在无效
关键字不存在。 pre-ANSI(K&安培; R)C方案将确定主
无论是作为
Prior to the publication of the 1989 ANSI C standard, the void
keyword did not exist. Pre-ANSI (K&R) C programs would define main
either as
main()
或
int main()
ANSI标准的主要目的是增加新的功能(包括
原型)的没有的破坏现有的pre-ANSI code。说明 INT的main()
不再有效,会违背这一目标。
A major goal of the ANSI standard was to add new features (including
prototypes) without breaking existing pre-ANSI code. Stating that
int main()
is no longer valid would have violated that goal.
我怀疑是C标准的作者没有的打算的
使 INT的main()
无效。但正如所写的标准不
反映的意图;但它至少的许可的一个符合标准的C语言编译器
拒绝 INT的main()
。
My suspicion is that the authors of the C standard did not intend
to make int main()
invalid. But the standard as written does not
reflect that intent; it at least permits a conforming C compiler
to reject int main()
.
的实际上的来说,你可以几乎肯定逃脱它。
我曾经尝试过每一个C编译器将接受
Practically speaking, you can almost certainly get away with it. Every C compiler I've ever tried will accept
int main() { return 0; }
毫无怨言,用相当于行为
without complaint, with behavior equivalent to
int main(void) { return 0; }
但是,对于各种原因:
But for a variety of reasons:
- 以下的文字和标准的意图;
- 避免使用过时的功能(将来的标准可以删除旧风格函数定义);
- 保持良好的编码习惯(
之间的差值()
和(无效)
是比<其它功能重要code>主
这实际上是由其他函数调用
我建议总是写 INT主要(无效)
,而不是 INT的main()
。
它规定的意图更加清晰,并且可以100%肯定,你的
编译器会接受它,而不是99.9%。
I recommend always writing int main(void)
rather than int main()
.
It states the intent more clearly, and you can be 100% sure that your
compiler will accept it, rather than 99.9%.
这篇关于为int的main(){}(不含&QUOT;无效&QUOT;)有效和便携式在ISO C?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!