函数名称范围如何跨多个C文件工作?
我正在将一个标准的gnu工具链项目移植到iPhone OS,并使用Xcode来完成它。
代码通过make构建,但不是通过xcode构建。当通过xcode构建时,链接器抱怨在两个对象中定义了相同的符号(函数)。代码有两个不同的源文件#include
它们之间的公共文件。虽然......奇怪(至少对我而言),它似乎适用于标准工具链。任何想法,如果这是通过标准的makefile以某种方式处理不同的东西?
答案 0 :(得分:4)
所有未标记为static的函数都具有全局范围(它们被转储到单个命名空间中)。标记为静态的函数仅限于它们所定义的转换单位。
您违反了One Definition Rule。
您的一个标题可能包含变量的定义。例如:common.h
你有
int foo = 42;
将其更改为:
extern int foo; // a declaration
然后创建一个common.c
文件,您可以在其中输入定义:
int foo = 42;
答案 1 :(得分:3)
在C中,如果我没记错的话,static
函数名称对于定义它们的源文件是本地的,但所有其他函数名称都存在于全局名称空间中。所以如果你有file1.c
void fn1() {}
static void fn2() {}
和file2.c
与
void fn1() {}
static void fn2() {}
你试图用
之类的东西编译它们cc file1.c file2.c
然后你会在fn1
中的file1.c
和fn1
中的file2.c
之间产生名称冲突,但不会在两个fn2
函数之间产生名称冲突(因为他们是静止的。 (当然,你也会得到一堆其他错误,因为这个程序不会做任何东西,但那些与范围界定无关。)
答案 2 :(得分:1)
我的猜测是公共头定义了一个内联函数,导致重复的符号。如果是这种情况,请使用static inline
为这些函数添加前缀,或者在另一个.c文件中将inline
声明定义为extern
。
答案 3 :(得分:1)
如果它从Makefile编译而没有错误,而不是来自你的XCode项目,那很可能是因为编译器的选项在两个环境中的设置不同。检查Makefile以查看传递给'gcc'的选项。特别是,重复定义可能是使用#ifdef进行条件编译的,您可能需要在XCode项目的设置中添加一些预处理器定义。