K& r的代码示例是否曾经符合?

发布于 2025-01-29 15:37:14 字数 754 浏览 3 评论 0原文

Brian Kernighan和Dennis Ritchie的C编程语言包含了许多示例,例如此著名的一种(K& r第二版1.1):

#include <stdio.h>

main()
{
  printf("hello, world\n");
}

我在这里注意到以下问题:

  • 否返回类型。

    在C90中允许使用不返回类型的写作功能,第二版本书声称要遵循。这些将在C90中默认为int。在语言的后期版本中,它是无效的。

  • 返回语句。

    具有返回类型的函数,否返回语句在C90中没有很好地定义。写main()没有返回等效于返回0;是C99中添加的功能。

  • 空的参数列表main()

    这是有效的C静止(从C17开始),但即使在C90中也一直是过时的功能。 (即将到来的C23谈论最终摆脱K&amp; r样式功能。)


我的问题:

k&amp; r第二版中的任何代码ever a e conforming程序在任何版本的标准中?

The C Programming Language by Brian Kernighan and Dennis Ritchie contains a lot of examples such as this famous one (K&R 2nd edition 1.1):

#include <stdio.h>

main()
{
  printf("hello, world\n");
}

Here I note the following issues:

  • No return type.

    Writing functions with no return type was allowed in C90 which the second edition of the book claims to follow. These will default to int in C90. It is invalid C in later versions of the language.

  • No return statement.

    A function with a return type and no return statement was not well-defined in C90. Writing main() with no return being equivalent to return 0; was a feature added in C99.

  • Empty parameter list of main().

    This is valid C still (as of C17) but has always been an obsolescent feature even in C90. (Upcoming C23 talks of finally getting rid of K&R style functions.)


My question:

Was any code in K&R 2nd edition ever a conforming program, in any version of the standard?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

爱人如己 2025-02-05 15:37:14

根据定义,通过符合C实现“接受”其“接受”其“接受”的任何源文本或集合都是“符合C程序”。因为实现了广泛的纬度,以任何不影响任何严格符合C程序的行为的方式扩展语言,所以任何不符合C程序的源文本t可以通过修改A来将其变成符合C程序符合C实施,以便如果给出了与t不匹配的程序,则它将正常处理,如果添加了T的副本,它的行为就会好像被给予了其他可以接受的其他程序。

尽管这似乎是一个荒谬的定义,但它满足了C标准委员会的主要目标之一,这是为了确保如果有任何现有计划可以完成任务,则可以通过符合C计划来完成任务。

至于该程序是否严格符合C89,这很难回答。该标准说,如果执行在main()的末尾都将返回到主机环境中,并且对这样做的后果没有任何要求,这将表明此类操作会调用不确定的行为。另一方面,标准 对如果程序返回exit_success,也不会议如果返回其他值。因此,所有这些行动都可以看作是援引未定义的行为。另一方面,以这种方式查看事物将使任何终止严格符合的程序都不可能。

我认为解释标准的最合理方法是说,执行过程中执行的程序放弃了其可能不得不影响执行环境终止的任何控制。如果所有行动方案在计划退出同样可以接受之后可以执行的行动方案,则程序未能做任何事情来影响采取哪种行动的任何事情将不是缺陷。

在考虑未能指定返回值的程序或该问题的任何程序是“严格符合”的程序时,不能仅仅检查源文本,但也必须考虑应用程序要求。如果一个人需要一个程序来输出字符x和y一次,以某种顺序将以下是一个严格符合的程序,该程序可以完成:

#include <stdio.h>
int outputx(void) { return printf("x"); }
int outputy(void) { return printf("y"); }
int main(void)
{
  return outputx() + outputy() && printf("\n") && 0;
}

如果另一方面,一个人需要一个程序来输出“ xy”,则为此目的,绝不是一个严格符合的程序。因此,我要说的是,如果某些任务的应用程序要求指定程序必须使用其返回值来影响主机环境,那么落在MAIN结束的程序将不是严格符合C程序来完成该任务。但是,如果对主机环境的这种影响不是任务应用程序要求的一部分,那么严格符合的C程序可以放弃这种控制。

引用下面:

N1570第4节第7节:

符合程序是一个符合实施的程序。 (*)5)严格符合的程序旨在在符合实施的情况下最大程度地携带。符合程序可能取决于符合实现的不可存储的特征。

未定义的行为定义为3.4.3:

行为,使用不可销的或错误的程序构建或错误的数据,该国际标准对此无需要求

C99理由没有任何要求,谈论符合的定义[强调原始]:

a 严格符合程序是最大便携式程序的另一个术语。目的是让程序员a 战斗机会制造强大的C程序,这些程序也很容易便携,而不会贬低完全有用的C程序,而cmative则不可便携,因此副词严格


程序未设置返回值的程序退出,这一事实可能使其不可存储,但是该标准是故意避免通过称其为不合格的“贬低”不可携带的程序。

By definition, any source text or collection thereof which is "accepted" by a Conforming C Implementation is a "Conforming C Program". Because implementations are given broad latitude to extend the language in any way which does not affect the behavior of any Strictly Conforming C Programs, any source text T which would not otherwise be a Conforming C Program could be turned into a Conforming C Program by modifying a Conforming C Implementation so that if it were given program that doesn't match T, it would process it normally, and if fed a copy of T it would behave as though it were fed some other program that it would accept.

While this may seem an absurdly broad definition, it satisfies one of the major goals of the C Standards Committee, which was to ensure that if any existing programs could accomplish a task, the task could be accomplished by a Conforming C Program.

As for whether the programs were Strictly Conforming under C89, that's a bit harder to answer. The Standard says that if execution falls through the end of main() it will return an Undefined Value to the host environment, and imposes no requirements about the consequence of doing so, which would suggest that such an action would invoke Undefined Behavior. On the other hand, the Standard also imposes no requirements upon what happens if a program returns EXIT_SUCCESS, nor what happens if it returns EXIT_FAILURE, nor if it returns some other value. Thus, all such actions could be viewed as invoking Undefined Behavior. On the other hand, viewing things in such fashion would make it impossible for any program which terminates to be Strictly Conforming.

I think the most reasonable way of interpreting the Standard would be to say that a program whose execution falls through the end of main() waives any control it might have had to affect what the execution environment does once it terminates. If all courses of action the host environment could perform after a program exits would be equally acceptable, a program's failure to do anything to influence which course of action is taken would not be a defect.

In considering whether a program that fails to specify a return value, or any program for that matter, is "Strictly Conforming", one cannot merely examine the source text, but must also consider the application requirements. If one needs a program to output the characters x and y once each, in some order, the following would be a strictly conforming program that accomplishes that:

#include <stdio.h>
int outputx(void) { return printf("x"); }
int outputy(void) { return printf("y"); }
int main(void)
{
  return outputx() + outputy() && printf("\n") && 0;
}

If, on the other hand, one need a program to output "xy", the above would not be a strictly conforming program for that purpose. Thus, I would say that if the application requirements for some task specify that a program must use its return value to influence the host environment, a program that falls through the end of main would not be a Strictly Conforming C Program to accomplish that task. If, however, such influence over the host environment is not part of the application requirements for a task, then a Strictly Conforming C Program could waive such control.

Citations below:

From N1570 section 4 pararaph 7:

A conforming program is one that is acceptable to a conforming implementation. (*) 5) Strictly conforming programs are intended to be maximally portable among conforming implementations. Conforming programs may depend upon nonportable features of a conforming implementation.

Undefined Behavior is defined in 3.4.3:

behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements

From the C99 Rationale, talking about the definition of conformance [emphasis original]:

A strictly conforming program is another term for a maximally portable program. The goal is to give the programmer a fighting chance to make powerful C programs that are also highly portable, without seeming to demean perfectly useful C programs that happen not to be portable, thus the adverb strictly.

The fact that a program exits without setting a return value may make it non-portable, but the Standard deliberately avoids "demeaning" non-portable programs by calling them non-conforming.

﹏半生如梦愿梦如真 2025-02-05 15:37:14

编译了该程序

#include <stdio.h>

main()
{
    printf("hello, world\n");
}

我在两个备受赞誉的编译器下 ,gccclang。只是为了好玩,我还添加了- pedantic选项。据我所知,这两个编译器都将被视为“符合”,我相信这是他们的作者当然要努力的事情之一。

两个编译器都产生了一个可执行的可执行文件,该可执行文件打印Hello,World。根据定义

一个符合程序是一个符合实施的程序

可以接受的程序。

我得出结论,

。我没有对该计划是否会根据C89符合的判断。

尽管我没有多年来研究过K&amp; r2中的代码示例,但我认为,尽管大多数/所有人都同样符合符合的代码,尽管各种教学或其他捷径可能会使它们不符合严格符合。

I compiled the program

#include <stdio.h>

main()
{
    printf("hello, world\n");
}

under two well-regarded compilers, gcc and clang. Just for fun I added the --pedantic option also. As far as I know both of these compilers would be considered "conforming", and I believe that's one of the things their authors certainly strive for.

Both compilers produced an executable which printed hello, world. Under the definition that

A conforming program is one that is acceptable to a conforming implementation

, I conclude that the program is conforming.

I pass no judgement on the question of whether the program would have been conforming under C89.

Although I have not studied the code examples in K&R2 in some years, I believe that most/all of the rest of them are similarly conforming, despite various pedagogical or other shortcuts which might render them not strictly conforming.

网名女生简单气质 2025-02-05 15:37:14

一些引号:

“第一版,1978年2月22日出版,是第一本关于C编程语言的广泛可用书。有时将其版本称为K&amp; rc(本书的作者之后),通常是为此而区分的。后来版本C的早期版本标准化为ANSI c。”

c 换句话说,K&amp; r Edition 1早于任何官方C标准。当时,唯一的规范是Dennis M. Ritchie的“ C参考手册”。


“ 1988年4月,该书的第二版出版,以涵盖当时新的ANSI C标准所产生的语言的更改,尤其是在标准库中包含参考材料时。”

(source wikipedia> wikipedia

)第一官方ANSI C标准,也称为C89。


但是,当时K&amp; r Edition 2出版了,C89尚未完成。根据

“ 1983年,美国国家标准研究所成立了一个委员会X3J11,为C. 1985年的标准规范。第一个标准草案被释放,有时称为C85。1986年,另一项草案标准已发布,有时称为C86。

。 =“ nofollow noreferrer”> wikipedia )

因此,它们可能是k&amp; r所说的内容与ANSI C标准之间的差异。

Some quotes:

"The first edition, published February 22, 1978, was the first widely available book on the C programming language. Its version of C is sometimes termed K&R C (after the book's authors), often to distinguish this early version from the later version of C standardized as ANSI C."

(source Wikipedia)

In other words, K&R edition 1 predates any official C standards. At the time the only specification was "The C Reference Manual" by Dennis M. Ritchie.


"In April 1988, the second edition of the book was published, updated to cover the changes to the language resulting from the then-new ANSI C standard, particularly with the inclusion of reference material on standard libraries."

(source Wikipedia)

In other words, K&R edition 2 was "aligned with" the first official ANSI C standard otherwise known as C89.


However, at the time K&R edition 2 was published, C89 was not yet complete. According the the Wikipedia page on ANSI C.

"In 1983, the American National Standards Institute formed a committee, X3J11, to establish a standard specification of C. In 1985, the first Standard Draft was released, sometimes referred to as C85. In 1986, another Draft Standard was released, sometimes referred to as C86. The prerelease Standard C was published in 1988, and sometimes referred to as C88."

(source Wikipedia)

Thus, they may be differences between what K&R says and the ANSI C standard.

我家小可爱 2025-02-05 15:37:14

不,K&amp; r Book中的程序从来都不是符合程序 1)(C17 4/7),根据标准的任何经验。

  • 在C90(ISO 9899:1990)中,由于缺少返回语句,代码调用了未定义的行为。
  • 在C99(ISO 9899:1999)及以后,由于隐式int,代码不会编译。

以下资源。


关于隐式int,可以在此处找到C90和后者版本之间函数返回类型的一个主要差异:

C90 6.7.1功能定义

函数的返回类型应为void或数组以外的对象类型。
/ - /
如果声明器包括一个iDenfifier列表,则可以在以下声明列表中声明参数的类型。任何未声明的参数具有类型int

C17 6.9.1功能定义

函数的返回类型应为void或其他数组以外的完整对象类型
类型。
/ - /
如果是
声明器包括标识符列表,参数的类型应在
以下声明列表。无论哪种情况,每个参数的类型均被调整为
在6.7.6.3中描述了参数类型列表;结果类型应为一个完整的对象
类型。

主要区别是“完整的对象类型”措辞,完整对象类型的定义是基本类型之一或指针之一(C17 6.2.5)。我们可以得出结论,在C90中允许隐式int作为返回类型或(非概率)参数列表的一部分。


关于返回语句,此文本始终存在用于一般函数:

C90 6.6.6.4

如果执行没有表达式的返回语句并且函数调用的值由呼叫者使用,则行为是未定义的。终止函数的}等同于执行返回语句而没有表达式。

C17 6.9.1/12

如果终止函数的},函数调用的值由
呼叫者,行为不确定。

中添加了例外情况。

但是,main()是一种特殊情况,在C99: C99 5.1.2.2.3

如果main函数的返回类型与int兼容的类型,则从
main函数的初始调用等效于调用exit用值
main函数作为其参数返回;到达}终止
MAIN函数返回0的值。

而在C90中,等效文本说:

C90 5.1.2.2.3

从初始调用到main函数的返回等同于调用exit函数
main函数作为其参数返回的值。如果main函数执行
返回没有值的返回,返回到主机环境的终止状态不确定。


关于空参数列表,它已被标记为从C90到C17的过时。请参阅未来的语言方向,例如C17 6.11(或C90 6.9,相同的文本):

6.11.6功能声明器
使用带有空括号的功能声明器(不是原型 - 格式参数类型
声明器)是一个过时的功能。

6.11.7功能定义
使用单独的参数标识符和声明列表的函数定义的使用(不是原型Format
参数类型和标识符声明器)是一个过时的功能。

但是,这并不意味着使用该功能的代码不符合符合,至少直到ISO 9899:2018。这根本不是建议的练习,也不是在发布K&amp; r第二版的时候推荐的练习。


1) C17来自CHP 4:

符合实施的实施可能具有扩展名(包括
额外的库功能),只要它们不会严格改变任何行为
符合程序。

a 符合程序是一个符合实现的方法。

a 严格符合程序应仅使用语言和库的那些功能
在此国际标准中指定。它不会产生取决于任何的产出
未指定,未定义或实施定义的行为,不得超过任何最低实施限制。

这意味着一个符合程序可能会使用不可存储的符合实现的功能,但是它可能不会通过例如在标准中调用不确定的行为来改变严格符合程序的行为。

No, the programs in the K&R book were never conforming programs 1) (C17 4/7) under any verison of the standard.

  • In C90 (ISO 9899:1990), the code invoked undefined behavior because of the missing return statement.
  • In C99 (ISO 9899:1999) and beyond, the code won't compile because of the implicit int.

Sources below.


Regarding implicit int, one major difference in function return types between C90 and latter versions can be found here:

C90 6.7.1 Function definitions

The return type of a function shall be void or an object type other than array.
/--/
If the declarator includes an idenfifier list, the types of the parameters may be declared in a following declaration list. Any parameter that is not declared has type int.

C17 6.9.1 Function definitions

The return type of a function shall be void or a complete object type other than array
type.
/--/
If the
declarator includes an identifier list, the types of the parameters shall be declared in a
following declaration list. In either case, the type of each parameter is adjusted as
described in 6.7.6.3 for a parameter type list; the resulting type shall be a complete object
type.

The main difference being the "complete object type" wording, the definition of complete object type being one of the basic types or a pointer to one (C17 6.2.5). We can conclude that implicit int was allowed in C90 both as the return type or as part of a (non-prototype) parameter list.


Regarding no return statement, this text was always there for general functions:

C90 6.6.6.4

If a return statement without an expression is executed and the value of the function call is used by the caller, the behavior is undefined. Reaching the } that terminates a function is equivalent to executing a return statement without an expression.

C17 6.9.1/12

If the } that terminates a function is reached, and the value of the function call is used by
the caller, the behavior is undefined.

However, main() is a special case and an exception was added in C99:

C99 5.1.2.2.3

If the return type of the main function is a type compatible with int, 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; reaching the } that terminates the
main function returns a value of 0.

Whereas in C90, the equivalent text says:

C90 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. If the main function executes a
return that specifies no value, the termination status returned to the host environment is undefined.


Regarding empty parameter lists, it has been marked as obsolescent from C90 to C17. See future language directions, for example C17 6.11 (or C90 6.9, identical text):

6.11.6 Function declarators
The use of function declarators with empty parentheses (not prototype-format parameter type
declarators) is an obsolescent feature.

6.11.7 Function definitions
The use of function definitions with separate parameter identifier and declaration lists (not prototypeformat
parameter type and identifier declarators) is an obsolescent feature.

This does however not mean that code using the feature isn't conforming, at least up to ISO 9899:2018. It's simply not recommended practice, and was not recommended practice at the point where K&R 2nd edition was released either.


1) C17 from chp 4:

A conforming implementation may have extensions (including
additional library functions), provided they do not alter the behavior of any strictly
conforming program.

A conforming program is one that is acceptable to a conforming implementation.

A strictly conforming program shall use only those features of the language and library
specified in this International Standard. It shall not produce output dependent on any
unspecified, undefined, or implementation-defined behavior, and shall not exceed any minimum implementation limit.

This means that a conforming program may use features of a conforming implementation that are non-portable, but it may not alter the behavior of a strictly conforming program by for example invoking undefined behavior explicitly listed as such in the standard.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文