我已经阅读了最后的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的弱函数来实现它,然后调用并返回方法本身 - 但问题仍然存在,它是否符合要求?
谢谢!
答案 0 :(得分:1)
您描述的所有内容听起来都符合语言链接功能的意图。
类成员被明确排除在"C"
语言链接之外。根据标准(C ++11§7.5/ 4)中的示例,类成员声明中的函数指针类型,任何上下文中的extern
声明以及所有其他函数声明都会继承封闭的extern "C" {}
块。您正在定义除"C"
之外的语言链接,但遵循其示例最不可能,可能是this
和self
之间的额外映射。
根据§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不需要支持任何重整。所以你的方案至少可以打破 。