Я прочитал последний черновик C ++ 11 (n3337 — это последний?), И у меня возник вопрос о возможной реализации, над которой я работал.
Допустим, у нас есть этот код:
extern "Objective C" {
class Object {
public:
static Object *alloc();
Object *init();
};
};
Потом звоню
Object *x = Object::alloc()->init();
Вопрос в том, что я не понял, разрешено ли компилятору управлять соглашением о вызовах внешних «X» -блоков: идея состояла бы в том, чтобы «перевести» вызовы objc_msgSend (blablabla) — будет ли это соответствовать стандарт, или это будет считаться расширением (так как это не просто изменило бы имя символа, но и сложное «соглашение о вызовах» здесь)? Конечно, я мог бы реализовать это, создав слабую функцию, которая называется __thiscall, а затем вызывает и возвращает сам метод — но вопрос остается, будет ли он соответствовать?
Спасибо!
Все, что вы описываете, звучит так, чтобы соответствовать цели языковой связи.
Члены класса специально исключены из "C"
языковая связь. Согласно примерам в Стандарте (C ++ 11 §7.5 / 4), типы указателей на функции в объявлениях членов класса, extern
объявления в любом контексте и все другие объявления функций наследуют extern "C" {}
блок. Вы определяете языковые связи помимо "C"
но было бы наименее удивительно следовать его примеру, возможно, с дополнительным отображением между this
а также self
,
Требования являются открытыми, в соответствии с §7.5 / 2:
Использование Строка литерала кроме «C» или «C ++» поддерживается условно с определенной семантикой реализации. [Примечание: Следовательно, спецификация связи со строковым литералом, который неизвестен реализации, требует диагностики. — примечание конца] [Примечание: рекомендуется, чтобы написание строкового литерала было взято из документа, определяющего этот язык. Например, Ада (не АДА) и Фортран или Фортран, в зависимости от винтажа. — конец примечания]
Вы можете переключиться на совершенно другой язык в скобках, и все будет в порядке. (Хотя, грамматически, я полагаю, все должно анализироваться как C ++ декларация или же Заявление-сл.)
В соответствии с этим, однако, вы должны использовать extern "Objective-C"
с дефисом, поскольку окончательное название документа — «Язык программирования Objective-C».
РЕДАКТИРОВАТЬ: Чтобы быть уверенным, позвонив через objc_msgSend
не влияет ни на что, указанное в стандарте. Нигде не говорится, как называются функции C ++. Добавленная промежуточная функция — это просто инструкции машинного уровня, выходящие за рамки семантики языка, и ничем не отличающиеся от специальных инструкций, используемых для вызова в Pascal, Fortran и т. Д., Например изменяя порядок параметров в стеке. Я не хочу сравнивать вашу схему с «переключением на совершенно другой язык в фигурных скобках», просто чтобы подчеркнуть, что есть много свободного места.
Принимая extern "C"
спецификация в Стандарте в качестве примера, она ломает много вещей, фундаментально изменяя правило ODR, потому что C не требует поддержки какого-либо искажения. Таким образом, ваша схема может быть нарушена по крайней мере столько.
Других решений пока нет …