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

标签 c++ objective-c extern linkage

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

假设我们有这段代码:

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

然后调用

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

问题是我不明白是否允许编译器控制外部“X” block 的调用约定:这个想法是“翻译”对 objc_msgSend(blablabla) 的调用 - 那会是符合标准,还是将其视为扩展(因为它不仅会修改符号名称,还会在这里修改复杂的“调用约定”)?当然,我可以通过创建一个称为 __thiscall 的弱函数来实现这一点,然后调用并返回方法本身——但问题仍然存在,它是否符合要求?

谢谢!

最佳答案

您描述的一切听起来都符合语言链接功能的意图。

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

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

Use of a string-literal other than "C" or "C++" is conditionally-supported, with implementation-defined semantics. [ Note: Therefore, a linkage-specification with a string- literal that is unknown to the implementation requires a diagnostic. — end note ] [ Note: It is recommended that the spelling of the string-literal be taken from the document defining that language. For example, Ada (not ADA) and Fortran or FORTRAN, depending on the vintage. — end note ]

你可以在大括号内切换到完全不同的语言,这样就没问题了。 (尽管从语法上讲,我认为所有内容都应该解析为 C++ 声明声明序列。)

尽管如此,您应该使用带连字符的 extern "Objective-C",因为权威文档的标题是“The Objective-C Programming Language”。

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

以标准中的extern "C"规范为例,它从根本上改变了ODR规则,打破了很多东西,因为C不需要支持任何修饰。所以你的方案被允许破坏至少那么多。

关于关于外部链接和调用约定的 C++ 标准,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14616979/

相关文章:

c++ - C++ 中的静态鸭子类型(duck typing)

c++ - 获取级联 TouchEvent 的目标不起作用

objective-c - cocoa 变量声明

JavaScript setAttribute 到另一个元素

c++ - 转换因参数类型而异的函数指针

c++ - 将今天的日期变成变量

ios - 使用 sections 将 indexPath 减一

objective-c - 在线程崩溃中调用NSPathControl对象

c - 在 C 中访问链接器定义的符号

android - 导出 C 局部变量 : JNI run-time behavior issue