gpt4 book ai didi

c - C 中头文件的目的只是警告用户吗?

转载 作者:行者123 更新时间:2023-11-30 18:45:58 26 4
gpt4 key购买 nike

我是链接的初学者,如果我的问题太基础,我很抱歉。假设我有两个 .c 文件

file1.c 是

int main(int argc, char *argv[]) 
{
int a = function2();
return 0;
}

file2.c 是

int function2() 
{
return 2018;
}

我知道规范是创建一个 file2.h 并将其包含在 file1.c 中,我有一些问题:

Q1。 #include in file1.c 对我来说并没有太大的区别或改进,我仍然可以正确编译没有 file2.h 的 file1.c,编译器只会警告我“隐式声明函数 'function2 ',但是这个警告有很大帮助吗?程序员可能知道 function2 是在其他 .c 文件中定义的(如果您使用 function2 但没有定义它,您当然知道定义在其他地方)并且链接器将完成其工作以生成最终的可执行文件?所以 include file2,c 对我来说的唯一目的是,在编译过程中不显示任何警告,我的理解是否正确。

第二季度。想象一下这个场景,一个程序员在 file1.c 中定义了 function2,他不知道他的 function2 与 file2.c 中的 function2 冲突,直到链接器抛出错误(显然他可以单独正确编译他的 file1.c。但是如果我们想让他在编译file1.c时知道自己的错误,添加file2.h仍然没有帮助,那么添加头文件的目的是什么?

第三季度。我们应该添加什么来让程序员知道他应该为 function2 选择不同的名称,而不是在最后阶段由链接器告知错误。

最佳答案

C89 3.3.2.2 Function calls强调我的:

If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier, and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if, in the innermost block containing the function call, the declaration

    extern int  identifier();

appeared

现在,请记住,空参数列表(() 大括号内没有任何内容进行声明)声明了一个采用未指定类型和参数数量的函数。类型void在大括号内声明函数不带参数,例如 int func(void) .

第一季度:

does this warning help a lot?

是和否。这是一个主观问题。它可以帮助那些使用它的人。作为个人说明,请始终将此警告设置为错误。使用gcc编译器使用-Werror=implicit-function-declaration 。但你也可以忽略这个警告,做最简单的main() { printf("hello world!\n"); }程序。

linker will do its job to produce the final executable file? so the only purpose of include file2,c to me is, don't show any warning during compilation, is my understanding correct.

没有。在使用不同/不兼容的指针类型调用函数的情况下。它调用未定义的行为。如果函数声明为void (*function2(void))(int a);然后调用((int(*)())function2)()正在调用 function2() 时是 UB没有事先声明。根据附件 J.2(资料性):

The behavior is undefined in the following circumstances:

A pointer is used to call a function whose type is not compatible with the pointed-to type (6.3.2.3).

并根据C11 6.3.2.3p8 :

A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.

所以在你幸运的情况下int function2()确实这有效。它也适用于例如 atoi()功能。但打电话atol()将调用未定义的行为。

第二季度:

the linker throws the error

这应该发生,但实际上取决于链接器。如果您使用 gcc 编译器的单个阶段编译所有源代码,则会抛出错误。但是,如果您创建静态库,然后使用 gcc 编译器链接它们,而无需 -Wl,-whole-archive然后它会选择看到的第一个声明,参见 this thread .

what's the purpose of adding header file?

我认为简单和秩序。它是在开发人员和库之间共享数据结构(枚举、结构、typedef)和声明(函数和变量类型)的便捷且标准的方法。还可以共享预处理器指令。想象一下,您正在编写一个包含 1000 多个文件的大型库,该库可以与 100 多个其他库一起使用。在每个文件的开头你会写struct mydata_s { int member1; int member2; ... }; int printf(const char*, ...); int scanf(const char *, ...); etc.或者只是 #include "mydata.h"#include <stdio.h> ?如果您需要更改 mydata_s结构,您需要更改项目中的所有文件,并且使用您的库的所有其他开发人员也需要更改定义。我并不是说你不能这样做,但这样做会花费更多的工作,而且没有人会使用你的库。

第三季度:

What should we add to let the programmer know he should choose a different name for function2 rather then be informed the error by linker in the final stage.

如果发生名称冲突,链接器会(希望)通知您它发现了两个具有相同名称的标识符。您需要创建一个工具来准确检查您的来源。我不知道为什么需要这个,链接器是专门为解析符号而设计的,因此它自然地处理存在两个具有相同标识符的符号的情况。

关于c - C 中头文件的目的只是警告用户吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53254290/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com