简单C内联链接器错误

简单C内联链接器错误,c,inline,linker-errors,C,Inline,Linker Errors,简单问题: 鉴于以下计划: #include <stdio.h> inline void addEmUp(int a, int b, int * result) { if (result) { *result = a+b; } } int main(int argc, const char * argv[]) { int i; addEmUp(1, 2, &i); return 0; } 似乎它并不费心去编译它

简单问题:

鉴于以下计划:

#include <stdio.h>

inline void addEmUp(int a, int b, int * result)
{
    if (result) {
        *result = a+b;
    }
}

int main(int argc, const char * argv[])
{
    int i;
    addEmUp(1, 2, &i);

    return 0;
}
似乎它并不费心去编译它

根据我在书中读到的内容,我不认为它应该是静态的 (因为这是在另一个对象中,并且处理2个定义而不是零)

这是一个相关的链接,但它是C++,我认为在STD C中把代码放在页眉中不是很好的做法:

编译器信息:

cc --version
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.3.0
Thread model: posix
编译示例:

# cc main.c 
Undefined symbols for architecture x86_64:
  "_addEmUp", referenced from:
      _main in main-sq3kr4.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocatio

尝试将“-O”选项添加到编译器命令中。只有在启用优化时才打开内联。

第6.7.4节第7段说:

任何具有内部链接的函数都可以是内联函数。对于具有外部链接的函数,以下限制适用:如果函数是用
内联
函数说明符声明的,则它也应在同一翻译单元中定义。如果翻译单元中某个函数的所有文件范围声明都包含
inline
函数说明符,而不包含
extern
,则该翻译单元中的定义为内联定义内联定义不为函数提供外部定义,也不禁止在其他翻译单元中使用外部定义。内联定义提供了外部定义的替代方法,转换器可以使用外部定义在同一翻译单元中实现对函数的任何调用未指定函数调用是使用内联定义还是外部定义

您的文件不包含
addEmUp
的外部定义,编译器选择在
main
中的调用中使用外部定义


提供外部定义,或将其声明为
静态内联
由于6.9/5,程序会导致未定义的行为(无需诊断),有时非正式地称为“一个定义规则”:

如果在表达式中使用了通过外部链接声明的标识符(而不是作为sizeof或_Alignof运算符的操作数的一部分,其结果是整数常量),则整个程序中的某个地方应该只有一个标识符的外部定义;否则,不得超过一个

程序使用标识符
addEmUp
,但不提供外部定义。(如前所述,“内联定义不提供函数的外部定义”)


我们不需要开始讨论函数调用的定义等。ODR冲突未定义且不需要诊断的原因是为了使编译器编写器更容易;如果此代码需要诊断,则编译器必须在禁用内联优化的情况下进行传递,以检查是否存在外部定义,这确实是浪费时间。

您使用哪个命令进行编译?您使用的编译器是什么?xcode 4.6.2中的clang确实消除了链接器错误,但是如果它不能内联,它不应该忽略关键字吗。。。无论如何,这只是一个暗示,GCC就是这么做的。Clang试图遵守C99,C99的解释似乎有点不同,这就是为什么您会遇到这个问题。静态内联不起作用(至少在实际项目中不起作用;没有尝试示例一)。。。我找到了一个Objective-C特定的宏,它确实可以工作,我正在更新。
静态内联
应该可以工作。你能把它简化到链接器错误仍然存在,但是代码足够小吗?如果它只在一个文件中使用,那么它也应该在实际项目中工作。好的,您总是可以选择提供一个外部定义来回溯。下面是详细说明差异的clang参考:
# cc main.c 
Undefined symbols for architecture x86_64:
  "_addEmUp", referenced from:
      _main in main-sq3kr4.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocatio