为什么#包括LT&;&stdio.h中GT;不需要用printf()? [英] Why #include <stdio.h> is not required to use printf()?

查看:334
本文介绍了为什么#包括LT&;&stdio.h中GT;不需要用printf()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

会话成绩单:

 >类型lookma.c
诠释主(){
  的printf(%S,无stdio.h中);
}> CL lookma.c
微软(R)32位C / C ++优化编译器版本为14.00.50727.762的80x86
版权所有(C)微软公司。版权所有。lookma.c
微软(R)增量链接器版本8.00.50727.762
版权所有(C)微软公司。版权所有。/out:lookma.exe
lookma.obj> lookma
没有stdio.h中


解决方案

在严格遵守模式(意思是理论上),您未定义行为(这是坏的),当你调用一个函数,采用可变数量的争论无范围的函数原型声明。这意味着,编译器可以做任何它喜欢与使用程序的printf()不受的#include&LT原型; stdio.h中&GT ; 或等效的声明。 任何它喜欢包括作为其中的一个选项正常工作;这似乎是选择你的榜样选择。

在实践中,code将工作与最实际的编译器确定,即使没有的printf()功能的正式声明。

正如指出的qrdl,该功能被发现,因为与C库中的C编译器的链接。

请注意,克里斯杨的约C99和隐式int的评论是准确的,但关于可变参数的函数必须在范围原型的规则适用于C89和C99。大多数编译器不严格的C99兼容模式在默认情况下,因为有太多的code,不会像编译的工作。

克里斯杨说:


  

要澄清,我的意见是在C99去除隐式声明。说隐式int,我想你指的是允许申报比如foo(无效)的C89功能;意味着INT富(无效);, C99的东西也被删除。


克里斯,当然,正确的。共有来自C99标准中删除两个隐式声明的特点。前言该标准列出了他们为:


  • 删除隐含 INT

  • 删除隐函数声明

我并没有考虑(因此不写)不够清楚。然而,无论是C89和C99要求范围的原型为带有可变数量的参数的函数。

要说明:

 的extern INT PQR();
INT主要(无效)
{
    INT I = PQR(1,3);
    返回我;
}

如果没有第一线,这与功能的隐式声明一个正确的C89片段 PQR()作为返回一个整数(含未指定参数)的功能。如果第一行是由的extern PQR()代替; ,那么这与的()显式声明PQR 作为返回一个整数(用一个未参数)的函数,但返回类型是隐性 INT 。按照规定,函数显式声明,并有明确 INT 返回类型 - 但它仍然有不确定的参数。我相信这是有效的C99 - 尽管并非完全不可取的。当然,海湾合作委员会(3.4.4)与选择接受它 -std = C99 -pedantic 。理想情况下,函数的声明应包括完整的原型。(如果 PQR()用省略号被定义,将要求原型的在理论上的!)

Session transcript:

>type lookma.c
int main() {
  printf("%s", "no stdio.h");
}

>cl lookma.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

lookma.c
Microsoft (R) Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:lookma.exe
lookma.obj

>lookma
no stdio.h

解决方案

In strict compliance mode (that means "in theory"), you invoke undefined behaviour (which is bad) when you call a function that takes a variable number of arguments without a prototype declaration of the function in scope. That means that the compiler is allowed to do anything it likes with a program that uses printf() without the prototype from #include <stdio.h> or an equivalent declaration. "Anything it likes" includes working correctly as one of the options; that seems to be the option chosen by your example.

In practice, the code will work OK with most practical compilers even without the formal declaration of the printf() function.

As was pointed out by qrdl, the function was found because the C compiler links with the C library.

Note that Chris Young's comment about C99 and 'implicit int' is accurate, but the rule about 'variable arguments functions must have a prototype in scope' applies to both C89 and C99. Most compilers do not work in a strict C99 compatibility mode by default because there is too much code that would not compile like that.

Chris Young commented:

To clarify, my comment was on C99 removing implicit declarations. By saying "implicit int", I think you are referring to the C89 feature of allowing declarations such as foo(void); to mean int foo(void);, something C99 also removed.

Chris is, of course, correct. There were two 'implicit declaration' features removed from the C99 standard. The foreword to the standard lists them as:

  • remove implicit int
  • remove implicit function declaration

I was not thinking (and hence not writing) clearly enough. Nevertheless, both C89 and C99 require a prototype in scope for functions that take a variable number of arguments.

To illustrate:

extern int pqr();
int main(void)
{
    int i = pqr(1, 3);
    return i;
}

Without the first line, this is a correct C89 fragment with an implicit declaration of the function pqr() as a function that returns an integer (with unspecified arguments). If the first line is replaced by extern pqr();, then this is a correct C89 fragment with an explicit declaration of pqr() as a function that returns an integer (with unspecified arguments), but the return type is 'implicit int'. As written, the function is explicitly declared and has an explicit int return type - but it still has unspecified arguments. I believe that is valid C99 - albeit not wholly desirable. Certainly, GCC (3.4.4) accepts it with the options '-std=c99 -pedantic". Ideally, the function declaration should include the full prototype. (And, if pqr() were defined with ellipsis, that prototype would be required in theory!)

这篇关于为什么#包括LT&;&stdio.h中GT;不需要用printf()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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