关于外部链接和调用约定的C ++标准

时间:2013-01-31 01:27:58

标签: c++ objective-c extern linkage

我已经阅读了最后的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的弱函数来实现它,然后调用并返回方法本身 - 但问题仍然存在,它是否符合要求?

谢谢!

1 个答案:

答案 0 :(得分:1)

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

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

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

  

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

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

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

编辑:确保通过objc_msgSend进行通话不会影响标准指定的任何内容。它没有说明如何调用C ++函数。添加的中间函数只是机器级指令,超出语言语义,与用于调用Pascal,Fortran等的特殊指令没有区别,例如:通过改变堆栈上参数的顺序。我并不是要将你的计划与“在括号内转换为完全不同的语言”进行比较,只是为了强调有足够的空间。

以标准中的extern "C"规范为例,它通过从根本上改变ODR规则来打破很多事情,因为C不需要支持任何重整。所以你的方案至少可以打破