从不同的c文件调用函数

时间:2014-09-02 07:17:02

标签: gcc compilation linker function-declaration definitions

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

文件main.c - >

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

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

档案1.c - &gt;

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

文件2.c - &gt;

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

现在我使用gcc编译如下 - &gt;

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

以下是输出 - &gt;

INSIDE foo1 function
INSIDE foo2 function
INSIDE foo3 function

我怀疑main()如何在foo1()中宣布foo2()时调用main.cfoo3()。但是现在如果我按照以下方式更改main.c(在main()之后写#include <stdio.h> int main() { foo1(); foo2(); foo3(); } void foo3(void) { printf("INSIDE foo3 function\n"); } 的定义),就像这样:

编辑main.c - &gt;

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()

为什么在foo2()和{{1}}的情况下,此错误未在前面显示。先感谢您。

1 个答案:

答案 0 :(得分:1)

  

我怀疑当main()

中没有宣布foo1() foo2()main.c时,int如何调用 gcc -std=c99 -Wall -g -c main.c gcc -std=c99 -Wall -g 1.c 2.c main.c -o main

因为GCC编译器默认使用旧的ANSI C(也称为C89)语言,允许使用未声明的函数,默认为提供gcc -flto结果。

尝试调用编译器,例如

gcc

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

-Wall

您可以使用最近的 link time interprocedural optimizations-g而不是main.c要求GCC,例如GCC 4.9于2014年9月举行。

这需要符合C99条件的源代码,其中应声明所有函数。 foo3要求(几乎)所有警告。 main选项生成可调试的目标代码(或最后一个命令的可执行文件,一次编译所有文件)。

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

您可以使用myheader.h警告option// 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"隐含此警告。)

在链接时,C函数的类型(和签名)无关紧要。链接器只使用name来完成它的工作(但是C ++使用name mangling)。当然,使用不正确的参数或结果调用函数是undefined behavior

良好的传统做法是有一个公共头文件,声明源文件中所有已使用和公共函数和类型(和常量)和include头文件(这样可以避免必须多次复制和粘贴这些声明)。所以你应该有一个新的头文件#include <stdio.h>,如

MY_HEADER_INCLUDED

并且您将在所有源文件中添加make(在Makefile指令之后)。请注意{{1}}的{​​{3}}技巧。

实际上,标题文件通常包含解释程序include guard的注释。

另请了解API。它将简化多源代码文件程序的构建(您只需通过运行{{1}}进行编译和构建)。请参阅{{1}}的{​​{3}}和GNU make示例。理解this是C编译的第一阶段。