Очень специфический угловой случай, который MSVC запрещает через Ошибка компилятора 2688 является признал Microsoft быть нестандартным поведением. Кто-нибудь знает, почему у MSVC ++ есть это конкретное ограничение?
Тот факт, что он предполагает одновременное использование трех языковых функций («виртуальные базовые классы», «ковариантные типы возвращаемых данных» и «переменное число аргументов», согласно описанию на второй связанной странице), которые являются семантически ортогональными и полностью поддерживаются отдельно похоже, подразумевает, что это не синтаксический или семантический вопрос, а ключевой случай в Microsoft C ++ ABI. В частности, тот факт, что задействовано «переменное число аргументов», (?) Предполагает, что ABI C ++ использует неявный конечный параметр для реализации комбинации двух других функций, но не может, потому что нет фиксированного места поставить этот параметр, когда функция имеет тип var arg.
Достаточно ли кто-нибудь знает ABI Microsoft C ++, чтобы подтвердить, так ли это, и объяснить, для чего используется этот неявный конечный аргумент (или что еще происходит, если мое предположение неверно)? Microsoft C ++ ABI не задокументирована, но я знаю, что некоторые люди за пределами Microsoft по разным причинам проделали работу по сопоставлению ABI, поэтому я надеюсь, что кто-то сможет объяснить, что происходит.
Кроме того, документация Microsoft немного противоречива; вторая ссылка на страницу говорит:
Виртуальные базовые классы не поддерживаются как ковариантные возвращаемые типы, когда виртуальная функция имеет переменное число аргументов.
но первая страница более широко гласит:
ковариантный возврат с несколько или виртуальное наследование не поддерживается для функций varargs
Кто-нибудь знает, что такое настоящая история? Я могу провести некоторые эксперименты, чтобы выяснить это, но я предполагаю, что фактический угловой случай не является ни одним из них, а именно, но связан со спецификой иерархии классов таким образом, что документаторы решили затушевывать. Я предполагаю, что это связано с необходимостью регулировки указателя в виртуальном блоке, но я надеюсь, что кто-то с более глубоким знанием ситуации, чем я, сможет объяснить, что происходит за капотом.
Я могу с уверенностью сказать вам, что MSVC C ++ ABI использует неявные дополнительные параметры для выполнения задач, которые в других ABI (а именно Itanium) реализуют несколько отдельных функций для обработки, поэтому нетрудно представить, что одна из них используется здесь (или будет, если дела были поддержаны).
Я не знаю наверняка, что происходит в этом случае, но кажется правдоподобным, что неявный дополнительный параметр передается в thunk, реализующий виртуальную функцию, требуется ли понижение до ковариантного класса возвращаемого типа (или, что более вероятно, требуется ли обратное преобразование к базовому классу, поскольку фактическая реализующая функция, вероятно, возвращает производный класс), и что этот дополнительный параметр остается последним, чтобы его могли игнорировать базовые классы (которые ничего не знали бы о коварианте вернуть).
Это подразумевает, что случай неподдерживаемого угла возникает всегда, когда виртуальный базовый класс является исходным типом возврата (так как для производного класса всегда будет требоваться thunk), что описано в первой кавычке; это также может произойти в некоторых, но не во всех случаях, связанных с множественным наследованием (возможно, поэтому оно включено во вторую цитату, но не в первую).
Других решений пока нет …