我已经阅读了最新的 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"
之外的语言链接,但遵循它的示例并不奇怪,也许在 this
和 self
之间有额外的映射>.
根据 §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/