我有一个小项目,我在两个不同的源文件中命名了两个相同的名称函数,但是在构建项目时,编译器失败并且'filename已经在filename.obj中定义了。
为什么我不能在两个不同的源文件中使用两个具有相同名称的函数?我认为该函数应该是源文件的本地函数,只有当我们在头文件中声明它时它才会变为全局。
除了更改文件名外,C编程语言中是否还有其他优雅的复制函数名解决方案?
答案 0 :(得分:34)
在C中,函数默认具有全局范围。要限制其范围,请使用static
关键字将其设置为模块的私有。
头文件的作用只是将函数及其签名公布给其他模块。
所有全球名称必须(有一些警告)是唯一的。这是有道理的,因为该名称是链接器用于将函数调用连接到函数本身的实现的名称。
具有静态和本地范围的名称只需在其范围内是唯一的。
答案 1 :(得分:8)
是否在头文件或源文件中声明某些内容对编译器没有任何区别。实际上,编译器本身对任何“头文件”都一无所知,因为头文件被所谓的预处理器嵌入到源文件中,它在编译器之前正常工作。当源文件(带有嵌入的头文件)到达实际的编译器时,无法分辨最初的内容和从头文件中插入的内容。包含所有头文件的源文件称为翻译单元。即编译器适用于翻译单元,而不是某些“源”或“标题”文件。
在C语言中,在文件范围内声明的所有对象和函数默认都具有外部链接,这意味着它们是全局的,对于整个程序是唯一的。所以,你想错了。函数不仅仅是一个源文件的本地函数。
如果要在单个翻译单元本地创建一个函数(或对象),则必须采取一些明确的步骤。您必须将其声明为static
。将其声明为静态将为其提供内部链接,这实际上意味着它成为其翻译单元的内部。
声明您的函数static
只有在它们都必须属于自己的翻译单元本地时才有效。如果不是这种情况,即如果至少有一个函数应该是全局可访问(可链接)函数,那么除了重命名其中一个函数之外别无选择。
答案 2 :(得分:7)
为什么我不能在两个不同的源文件中使用两个具有相同名称的函数?
因为链接器需要知道引用它时的含义。
想象一下,a.h
和b.h
都声明my_function()
。编译器为两者生成代码。现在,假设c.c
调用my_function()
- 链接器如何知道应该调用函数的两个版本中的哪一个?
答案 3 :(得分:4)
声明函数static
以使其成为文件的本地。在C中,每个标识符名称必须是唯一的。
答案 4 :(得分:3)
优雅的解决方案是C ++中引入的命名空间。解决方案,如果对func_name的调用很少,则选择一个,重命名并重新编译。
有些黑客但快速的解决方案可能就是这样:
//In one of the two source files and any file that calls it
//if your functions is something like this
//void func_name(int) { ... }
//Add the following line
#define func_name SOME_UNIQUE_FUNC_NAME