我们能在定义函数之前调用它吗?

8
#include <stdio.h>

void main()
{
    m();
}

void m()
{
    printf("hi");
}

输出

警告

main.c:11:10: warning: conflicting types for 'm' [enabled by default]
     void m()
          ^
main.c:7:9: note: previous implicit declaration of 'm' was here
         m();
         ^

为什么即使在定义 m() 之前就调用了它,此程序仍可以成功运行?警告的意义是什么?

2
你使用的是哪个编译器?其中一些(如Visual Studio)允许你编写不符合C99标准但可以成功运行的代码。 - Martin Perry
我正在使用CodeBlocks。 - Pankaj Mahato
6个回答

11

C89允许将函数的返回类型和传递给它的参数隐式转换为int。详情请参见此处

但是,这在C99及以上版本中无效。这已被省略从标准中省略。您需要声明函数的原型或在main之前定义它。请查看此处的结果。在这种情况下会出现编译时错误。


这在CodeBlocks和在线编译器中运行得非常完美。 - Pankaj Mahato
为什么它能够工作?即使我在main()之后定义了m()函数? - Pankaj Mahato
1
以C99模式编译您的代码。请参阅我的回答中的链接。 - haccks

9
如果在K&RC/C89中没有声明函数,它会被隐式声明为返回 int。由于您的函数返回 void,因此存在不匹配的情况。
如果添加原型:
void m(void);

......在它被调用之前,它会修复一些东西。


我知道,但为什么代码可以运行? 难道不应该有编译时错误吗? - Pankaj Mahato
@PankajMahato:至少据我所知,不行。如果您尝试使用不匹配的返回类型,则会出现未定义的行为,但由于您正在忽略它,因此您可能甚至已经定义了行为。 - Jerry Coffin

5
不可以,但是你可以声明它:
#include <stdio.h>

// declare m()
void m();

void main()
{
    // use m()
    m();
}

// define m()
void m()
{
    printf("hi");
}

是的,我知道可以声明它。但如果不声明它,它是如何运行的呢? - Pankaj Mahato

3

函数声明需要在第一次调用函数之前添加。完整的声明包括返回类型以及参数的数量和类型,这也被称为函数原型。

所以你缺少了函数原型。

将函数声明添加为 void m(); 到代码中。

编辑:

C程序允许使用向前声明

在您的情况下,void m();表示函数的前向声明,并且是函数的原型。处理此声明后,编译器将允许用户在程序的其余部分引用实体m

函数的定义必须在某个地方提供(同一个文件或其他文件,在其中链接器将负责正确匹配一个或多个对象文件中对特定函数的引用与其定义相匹配,该定义必须是唯一的):(来自维基百科页面

这就是为什么在主程序之后定义函数可以工作。


2
是的 - 这被称为使用原型。也就是说,将标签放入标签之前。

void m();

文件开头处


你回答了我的第二个问题。我也想要第一个。 - Pankaj Mahato
@Pankaj Mahato - 编译器会尝试做一个有根据的猜测(例如 int m();)来确认它是否有效。 - Ed Heal

0
不,你通常不能这样做。
如果在调用前未定义函数,那么代码将会打印出类似于以下的错误信息:

s.c: In function 'main':
s.c:4:1: warning: implicit declaration of function 'm' [-Wimplicit-function-declaration]
    4 | m();
      | ^
s.c: At top level:
s.c:8:6: warning: conflicting types for 'm'
    8 | void m(){
      |      ^
s.c:4:1: note: previous implicit declaration of 'm' was here
    4 | m();
      | ^

因此,声明方法在主方法之前或之内是一种良好的实践,特别是如果您正在定义超出主函数范围的方法。 以下是最佳实践的代码片段:

#include <stdio.h>
void m();

void main()

{

m();

}

void m()

{

printf("hi");

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接