gpt4 book ai didi

objective-c - 为什么我不能在头文件中定义纯 C 函数?

转载 作者:太空狗 更新时间:2023-10-30 03:23:44 25 4
gpt4 key购买 nike

当我尝试在类接口(interface)上方的头文件中定义 C 函数时,我总是遇到构建错误。

但是当我在实现文件中做同样的事情并在标题中给出声明时。一切顺利。

我想知道,为什么我在头文件中定义了枚举、结构、常量 NSString,为什么不是 C 函数?

最佳答案

这与 C 链接器(或链接编辑器)的工作方式有关。当 C 编译器遇到一个函数定义时,它会准备实现该函数的汇编代码,并用一个符号标记它,告诉链接器“这是具有这个名称的函数开始的地方”。符号通常用下划线命名,后跟函数名,例如_printf

如果您在头文件中定义函数,那么每个导入此头文件的 .c.m 文件都会编译该函数,并导致编译器发出相同的符号。链接器预计每个符号只找到一个实例,因此这是一个错误。

这与 #include 守卫的存在无关,也与使用 #import 而不是 #include 无关。 C 编译器在单独的翻译单元 上工作——这意味着单独的源文件。预处理器策略会阻止您将相同的头文件两次包含到单个源文件中,但不会采取任何措施来协调多个文件之间的事件。这意味着在不同的源文件中包含相同的 header 是有效的:这也意味着当您编译不同的文件时,它们可以(合法地)包含相同的符号。

链接编辑器的工作是将这些文件放在一起,解析编译时对未知符号的任何引用。如果您尝试将具有相同符号的对象(已编译和组装的翻译单元的名称)链接到相同的存档、共享库或可执行文件中,那么您将收到此处看到的错误。

解决方案:

  • 不要在头文件中定义函数,只需在那里声明它并在实现文件中定义它;正如您已经发现的那样有效。
  • 在 header 中定义函数,但仅在代码中的一个位置包含该 header 。出于设计原因,这通常是 Not Acceptable 。
  • 在 header 中使用修饰符inline 定义函数。内联函数只是被编译器复制到调用它们的函数中,因此永远不会为它们发出链接器符号。这有它自己的权衡,你 may wish to read more about .

关于objective-c - 为什么我不能在头文件中定义纯 C 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10242357/

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