是C函数原型不匹配仅仅是一个警告 [英] Is c function prototype mismatch merely a warning

查看:1350
本文介绍了是C函数原型不匹配仅仅是一个警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请看看我的codeS低于

please take a look at my codes below

#include <stdio.h>

void printOut()
{
 static int i = 0;
 if (i < 10)
 {
  printOut(i);
 }
}

int main(int argc, char *argv[])
{

  return 0;
}

我想应该有一个错误,由于我调用不存在的功能prototype.Actually中,code。与mingw5编译器,这是奇怪的,我编译好了,然后我改变Borland的编译器,我得到一个警告消息说,没有打印输出功能的原型,这是只是一个警告?更重要的是,在code以及执行没有任何弹出错误窗口。

i guess there should be an error due to my invoking the non-existed function prototype.Actually, the code compiles well with mingw5 compiler, which is weird for me, then i change to Borland Compiler, i get a warning message said that no printOut function prototype, is this only a warning ? What is more, the code executes well without any pop-up error windows.

推荐答案

您程序的行为是不确定的,因为你定义 printOut的()不带参数,但是你叫它有一个参数。你需要解决它。但是你在这样来诊断问题,编译器不需要这样写的。 (GCC,例如,不发出警告的参数不匹配,甚至与 -std = C99 -pedantic -Wall -Wextra -O3。)

Your program's behavior is undefined, because you define printOut() with no parameters, but you call it with one argument. You need to fix it. But you've written it in such a way that the compiler isn't required to diagnose the problem. (gcc, for example, doesn't warn about the parameter mismatch, even with -std=c99 -pedantic -Wall -Wextra -O3.)

造成这种情况的原因是历史性的。

The reasons for this are historical.

pre-ANSI C(1989年之前)没有原型;函数的声明不能指定期望的类型或数量的参数。功能的定义的,在另一方面,所指定的功能的参数,而不是在一个方式,该编译器可以使用来诊断不匹配的呼叫。例如,一个INT参数的函数可以声明(比如,在头文件)是这样的:

Pre-ANSI C (prior to 1989) didn't have prototypes; function declarations could not specify the expected type or number of arguments. Function definition, on the other hand, specified the function's parameters, but not in a way that the compiler could use to diagnose mismatched calls. For example, a function with one int parameter might be declared (say, in a header file) like this:

int plus_one();

和定义(比如,在相应的.c文件)是这样的:

and defined (say, in the corresponding .c file) like this:

int plus_one(n)
int n;
{
     return n + 1;
}

参数信息被埋葬的定义中。

The parameter information was buried inside the definition.

ANSI C添加原型,所以上面的可以这样写的:

ANSI C added prototypes, so the above could written like this:

int plus_one(int n);

int plus_one(int n)
{
    return n + 1;
}

但语言继续支持旧式声明和定义,以免破坏现有的code。就连即将到来的C201X标准仍允许pre-ANSI函数声明和定义,虽然他们已经过时了,现在22年。

But the language continued to support the old-style declarations and definitions, so as not to break existing code. Even the upcoming C201X standard still permits pre-ANSI function declarations and definitions, though they've been obsolescent for 22 years now.

在你的定义:

void printOut()
{
    ...
}

您使用的是旧式函数定义。它说,printOut的没有参数 - 但它不会让编译器警告你,如果你不正确地调用它。你的内部功能,您使用一个自变量调用它。此调用的行为是的未定义的。它可以悄悄地忽略无关的参数 - 或者可以想见,腐败堆栈,使你的程序可怕的死亡。 (后者的可能性不大;由于历史原因,大多数C调用约定可以容忍这样的错误)

you're using an old-style function definition. It says that printOut has no parameters -- but it doesn't let the compiler warn you if you call it incorrectly. Inside your function you call it with one argument. The behavior of this call is undefined. It could quietly ignore the extraneous argument -- or it could conceivably corrupt the stack and cause your program to die horribly. (The latter is unlikely; for historical reasons, most C calling conventions are tolerant of such errors.)

如果您希望您的打印输出()函数没有参数的的你想要的编译器抱怨,如果你不正确地调用它,把它定义为:

If you want your printOut() function to have no parameters and you want the compiler to complain if you call it incorrectly, define it as:

void printOut(void)
{
    ...
}

这是独一无二的把它用C编写正确的方法。

This is the one and only correct way to write it in C.

当然,如果你只是使你的程序这一变化,然后添加到通话printOut的()的main(),你有你的手一个无限递归循环。您可能希望打印()来采取 INT 参数:

Of course if you simply make this change in your program and then add a call to printOut() in main(), you'll have an infinite recursive loop on your hands. You probably want printOUt() to take an int argument:

void printOut(int n)
{
    ...
}


碰巧的是,C ++有不同的规则。 C ++是来源于C,但与向后兼容性关注较少。当Stroustrup的增加原型C ++,他完全放弃旧式声明。由于没有需要一个特殊情况无效标记为参数的功能,无效printOut的()在C ++ 的说明确表示, printOut的没有参数,并带有参数的调用是错误的。 C ++还允许无效printOut的(无效)与C兼容性,但是这可能不会经常使用(这是很少有用写code这两种有效的C和有效的C ++ 。)C和C ++是两种不同的语言;您应按照您正在使用任何语言的规则。


As it happens, C++ has different rules. C++ was derived from C, but with less concern for backward compatibility. When Stroustrup added prototypes to C++, he dropped old-style declarations altogether. Since there was no need for a special-case void marker for parameterless functions, void printOut() in C++ says explicitly that printOut has no parameters, and a call with arguments is an error. C++ also permits void printOut(void) for compatibility with C, but that's probably not used very often (it's rarely useful to write code that's both valid C and valid C++.) C and C++ are two different languages; you should follow the rules for whichever language you're using.

这篇关于是C函数原型不匹配仅仅是一个警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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