0

实际上我正在编译多个文件。以下是文件:

文件 main.c -->

#include <stdio.h>
void foo3(void)
{
        printf("INSIDE foo3 function\n");
}

int main()
{
        foo1();
        foo2();
        foo3();
}

文件 1.c -->

#include <stdio.h>
void foo1(void)
{
        printf("INSIDE foo1 function\n");
}

文件 2.c-->

#include <stdio.h>
void foo2(void)
{
        printf("INSIDE foo2 function\n");
}

现在我使用 gcc 编译如下-->

gcc 1.c 2.c main.c -o main

以下是输出->

INSIDE foo1 function
INSIDE foo2 function
INSIDE foo3 function

我的疑问是 () 如何main调用foo1()以及foo2()何时未在main.c. 但是现在,如果我将 main.c 更改如下(编写foo3()after的定义main()),如下所示:

编辑 main.c -->

#include <stdio.h>
int main()
{
        foo1();
        foo2();
        foo3();
}

void foo3(void)
{
        printf("INSIDE foo3 function\n");
}

然后如果我编译我得到这个错误:

main.c:9:6: warning: conflicting types for ‘foo3’ [enabled by default]
 void foo3(void)
      ^
main.c:6:2: note: previous implicit declaration of ‘foo3’ was here
  foo3();
  ^

foo1()为什么在and的情况下之前没有显示此错误foo2()。先感谢您。

4

1 回答 1

1

我的疑问是如何main()调用foo1()以及foo2()何时未声明它们main.c

因为GCC编译器默认使用旧的ANSI C(也称为 C89)语言,其中允许未声明的函数并默认给出int结果。

尝试调用编译器,例如

 gcc -std=c99 -Wall -g -c main.c

或(如果您想一次编译所有文件)

 gcc -std=c99 -Wall -g 1.c 2.c main.c -o main

您可以要求链接时间过程间优化gcc -flto而不是gcc使用最近的 GCC,例如 2014 年 9 月的 GCC 4.9

这将需要一个符合C99的源代码,其中应声明所有函数。-Wall要求(几乎)所有警告。该-g选项产生一个可调试的目标代码(或对上一个命令同时编译所有文件的可执行文件)。

在您编辑main.c时遇到foo3 第一次出现(内部main)时,编译器猜测它是一个返回的函数int。当编译器看到它的定义时,foo3它会正确地抱怨。

您可以使用-Wstrict-prototypes警告选项gcc-Wall我总是建议使用它暗示)。

在链接时,C 函数的类型(和签名)并不重要。链接器只是使用 name 来完成它的工作(但 C++ 使用name mangling)。当然,使用不正确的参数或结果调用函数是未定义的行为

良好的常规做法是有一个通用的头文件来声明所有使用的和公共的函数和类型(和常量),并将头文件包含在您的源文件中(这避免了必须多次复制和粘贴这些声明)。所以你应该有一个新的头文件myheader.h,比如

// file myheader.h
#ifndef MY_HEADER_INCLUDED
#define MY_HEADER_INCLUDED
void foo1(void);
void foo2(void);
void foo3(void);
#endif /*MY_HEADER_INCLUDED*/

并且您将添加#include "myheader.h"所有源文件(在#include <stdio.h>指令之后)。请注意包含保护技巧MY_HEADER_INCLUDED

实际上,头文件通常包含解释程序API的注释。

还可以了解GNU make。它将简化您的多源代码文件程序的构建(您只需通过运行编译和构建make)。见这个那个例子Makefile。了解C 预处理是 C 编译的第一阶段。

于 2014-09-02T07:20:55.850 回答