为int的main(){}(不含"无效")有效和便携式在ISO C? [英] Is int main() { } (without "void") valid and portable in ISO C?

查看:123
本文介绍了为int的main(){}(不含"无效")有效和便携式在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 of int 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆