简体   繁体   English

为什么在使用GCC进行编译时不必包含头文件?

[英]Why don't I have to include my header files when compiling with GCC?

It was my understanding that in order to use a function declared in a header file and defined in a matching source file, said header file must be included before main(). 据我了解,为了使用在头文件中声明并在匹配的源文件中定义的函数,必须在main()之前包含所述头文件。 So why does the following compile and run just fine using: 那么,为什么使用以下命令编译并运行正常:

gcc -o hello hellomain.c hello.c gcc -o hello hellomain.c hello.c

hellomain.c hellomain.c

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

    return 0;
}

hello.h 你好

#ifndef hello_h
#define hello_h

void helloPrint();

#endif

hello.c 你好ç

#include <stdio.h>

void helloPrint()
{
    printf("Hello, World!");
}

This is obviously a very simplified example but it illustrates my question; 这显然是一个非常简化的示例,但它说明了我的问题。 why don't I have to include "hello.h" in "hellomain.c"? 为什么我不必在“ hellomain.c”中包含“ hello.h”? Thanks! 谢谢!

When using a function without a prototype the compiler makes certain assumptions about its return type and the parameters it takes. 当使用没有原型的函数时,编译器会对它的返回类型和它所使用的参数做一些假设。 In this case these assumptions happen to be work, even if it assumes the function returns an int . 在这种情况下,即使假设函数返回一个int ,这些假设也可以奏效。


As Eric Postpischil notes in the comments, omitting the prototype is highly discouraged as it can lead to subtle bugs. 正如Eric Postpischil在评论中指出的那样,强烈建议省略原型,因为它会导致细微的错误。 You should always make sure your function calls have the needed prototypes available, preferably by including their corresponding headers. 您应始终确保函数调用具有可用的所需原型,最好通过包括它们的相应标头来实现。

When you use an undeclared function in a C source file, the compiler derives the parameters from the call and assumes a return type of int. 当您在C源文件中使用未声明的函数时,编译器将从调用中派生参数,并假定返回类型为int。

According to ISO Standard 'Programming Languages - C' 根据ISO标准“编程语言-C”

6.5.2.2 Function calls 6.5.2.2函数调用
6 If the expression that denotes the called function has a type that does not include a prototype, 6如果表示被调用函数的表达式的类型不包含原型,
... ...
If the number of arguments does not equal the number of parameters, the behavior is undefined. 如果参数数量不等于参数数量,则行为是不确定的。

This means, when you use a function without declaring it and the number of your arguments and the number of actual parameters of the function disagree, all bets are off. 这意味着,如果您在未声明函数的情况下使用该函数,并且参数个数与该函数的实际参数个数不一致,则所有选择均无效。

... ...
If the function is defined with a type that does not include a prototype, and the types of the arguments after promotion are not compatible with those of the parameters after promotion, the behavior is undefined, ... 如果使用不包含原型的类型定义函数,并且升级后的参数类型与升级后的参数类型不兼容,则行为未定义,...

Also, when you use a function without declaring it and the types of your arguments and the actual types of the function don't match, anything might happen. 同样,当您在未声明函数的情况下使用函数且参数类型与函数的实际类型不匹配时,可能会发生任何事情。

So, although it might work in some cases, you should declare the functions you use in your program. 因此,尽管在某些情况下可能会起作用,但是您应该声明在程序中使用的功能。 If you don't, the compiler cannot help and detect mismatches between function declarations and function calls. 如果您不这样做,编译器将无法帮助并检测函数声明和函数调用之间的不匹配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 编译 .i 或 .ii 文件时忽略 gcc 标志 -include - gcc flag -include ignored when compiling .i or .ii files 默认情况下如何包含某些头文件,这样我就不必在每个程序中输入它们 - how to include certain header files by default so that i don't have to type them in every programs 如果我不包含头文件,将会发生什么 - What will happen if I don't include header files 为什么在编译时需要包含.o文件? - Why do I need to include .o files when compiling? 为什么我在运行Ceedling时必须在C中重新包含header个文件? - Why do I have to re-include header files in C when running Ceedling? i686是32位吗? 为什么我的gcc / g ++无法编译.cpp和.c文件? - Is i686 32 bit? Why does my gcc/g++ fail compiling .cpp and .c files? 当两个文件相互包含时,为什么我不能有一个内部结构? - Why can't I have an inner structure when two files include each other? C:我们为什么要包含声明但未定义的头文件? - C: Why do we include header files, which declare but don't define? 我编译时在MYSYS2中设置了rpath为gcc,但是程序运行时找不到,这是为什么呢? - I set the rpath with gcc in MYSYS2 when compiling, but the program can't find it when running, so why? 编译内核模块源代码时如何包含标准头文件? - how to include standard header files when compiling a kernel module source?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM