目标C - C++ 关于外部链接和呼叫约定的标准

objective c - C++ Standard regarding external linkage and calling conventions

本文关键字:呼叫 约定 标准 链接 于外部 C++ 目标      更新时间:2023-10-16

我已经阅读了最后的 C++11 草案(n3337 - 它是最后一个吗?),我有一个关于我一直在研究的可能实现的问题。

假设我们有以下代码:

extern "Objective C" {
  class Object {
    public:
      static Object *alloc();
      Object *init();
  };
};

然后打电话

Object *x = Object::alloc()->init();

问题是我不明白编译器是否允许控制 extern "X" 块的调用约定:这个想法是将调用"翻译"为 objc_msgSend(blablabla) - 这是否符合标准,还是会被视为扩展(因为它不会只是修改符号名称, 但以及这里复杂的"呼叫约定")?当然,我可以通过创建一个弱函数来实现这一点,该函数被调用为 __thiscall 然后调用并返回方法本身 - 但问题仍然存在,它会符合吗?

谢谢!

您描述的所有内容听起来都符合语言链接功能的意图。

班级成员被明确排除在语言链接之外"C"。根据标准 (C++11 §7.5/4) 中的示例,类成员声明中的函数指针类型、任何上下文中的extern声明以及所有其他函数声明都会继承封闭extern "C" {}块。除了"C"之外,您还定义了语言链接,但遵循它的示例是最不足为奇的,也许在thisself之间有额外的映射。

根据§7.5/2,要求是开放的:

有条件地支持使用"C"或"C++"以外的字符串文本,并具有实现定义的语义。[ 注意:因此,具有实现未知的字符串文本的链接规范需要诊断。[ 注意:建议字符串文字的拼写取自定义该语言的文档。例如,Ada(不是ADA)和Fortran或FORTRAN,取决于年份。— 尾注 ]

您可以在大括号内切换到完全不同的语言,这样就可以了。(虽然,从语法上讲,我想一切都应该解析为C++声明声明-seq

但是,根据这一点,您应该使用带有连字符的extern "Objective-C",因为最终文档的标题是"Objective-C编程语言"。

编辑:可以肯定的是,通过objc_msgSend调用不会影响标准指定的任何内容。它没有说明如何调用C++函数。添加的中间函数只是机器级指令,超越了语言语义,与用于调用 Pascal、Fortran 等的特殊指令没有什么不同,例如通过更改堆栈上参数的顺序。我并不是要将您的方案与"在大括号内切换到完全不同的语言"进行比较,只是为了强调有足够的空间。

以标准中的extern "C"规范为例,它通过从根本上改变 ODR 规则打破了很多东西,因为 C 不需要支持任何重整。所以你的计划至少可以打破那么多。