Почему изменение имени не стандартизировано

Мне просто интересно, почему изменение имен никогда не стандартизировалось стандартом С++. Ясно, что наличие разных алгоритмов изменения имен ухудшает совместимость[1], и я не вижу никаких преимуществ в том, чтобы они определялись реализацией.

То есть, вопреки соглашениям о вызовах или размеру примитивов, самой машине все равно и даже не известно, как вызывается функция. Так почему же он не был стандартизирован и почему он до сих пор не стандартизирован? Компиляторы так или иначе изменили правила в прошлом между версиями.

[1] все эти люди, экспортирующие функции как extern "C", говорят о многом.


person Voo    schedule 12.04.2012    source источник
comment
Стандартизированное изменение имени служит только для того, чтобы дать вам ложное чувство безопасности, потому что вы также должны стандартизировать ABI, чтобы получить надлежащую совместимость. И комитет по стандартам C++ вряд ли будет заниматься стандартизацией ABI.   -  person Raymond Chen    schedule 12.04.2012
comment
+1 @Raymond - ложь себе о совместимости - плохие новости для всех. Это все равно, что полагаться на неопределенное поведение. Конечно, вы думаете, что это работает, но на самом деле это не так.   -  person Carl Norum    schedule 12.04.2012
comment
Правда, договориться о C++ ABI было бы намного сложнее, чем для C. Немного OT: Что именно в этом вопросе не считается подходящим для SO тремя людьми? В конце концов, совершенно очевидно, что существует хороший отчетливый ответ, как уже было показано.   -  person Voo    schedule 12.04.2012
comment
Здесь есть два вопроса: 1) Почему нет стандарта a для изменения имен и 2) Почему изменение имен не является частью ISO C++ 14882?   -  person MSalters    schedule 13.04.2012
comment
ABI связан с реализацией, то есть сильно зависит от машины. На разных машинах вы получите разные ABI, что не соответствует C++ как языку. Это больше в области ассемблера. Вот почему ABI не стандартизирован комитетом C++. Но его часто стандартизируют разработчики и разработчики машин, такие как Intel и т. д. Вот довольно подробное описание ABI Intel Itanium x86 для C++: sourcery.mentor.com/public/cxx-abi   -  person SasQ    schedule 03.08.2012
comment
Тот же ответ, что и все Почему XXX не стандартизирован: слишком сложно, недостаточно полезно, Microsoft хотела предотвратить совместимость и т. д. :-)   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 05.06.2015


Ответы (2)


В стандарте не рассматриваются детали реализации. Есть много-много вещей, которые зависят от реализации и которые мешают совместной работе программ: расположение классов, структура vtable и т. д. В общем, компиляторы изменят искажение имени, если они . Это сделано намеренно, так как предотвращает связывание кода, который не будет работать.

Для данной платформы возможно определение C++ ABI; все компиляторы, которые придерживаются его, будут использовать совместимые реализации и иметь общее искажение имен. Однако это проблема для поставщиков платформ; по тем или иным причинам очень немногие поставщики определили C++ ABI.

И причина, по которой extern "C" работает, заключается в том, что почти все платформы определяют C ABI.

person James Kanze    schedule 12.04.2012
comment
Следует добавить, что даже если бы изменение было стандартизировано, extern "C" все равно потребовалось бы, потому что C не выполняет никаких изменений, а C++ должен поддерживать перегруженные функции, поэтому символы в любом случае разные. - person Jan Hudec; 12.04.2012
comment
@JanHudec На самом деле не совсем понятно, что означает extern "C". Что это значит, например, на платформе, на которой нет компилятора C? Однако на практике большинство, если не все платформы определяют C ABI, и extern "C" означает придерживаться этого. И здесь искажение имен — не единственная проблема; Я работал на платформах, где переменные порядка помещались в стек, отличались между C и C++. (Кроме того, большинство компиляторов C, которые я использовал, искажают имена. Просто гораздо проще, чем C++.) - person James Kanze; 12.04.2012

Стандарт на самом деле не требует искажения имен. Если уж на то пошло, стандарт не требует чисел с плавающей запятой IEEE или чего-либо еще.

Пока не появился широко распространенный ABI, на который можно было положиться, GCC на самом деле изо всех сил старался использовать другую схему искажения имен, чем его конкуренты:

G++ не искажает имена так, как другие компиляторы C++. Это означает, что объектные файлы, скомпилированные одним компилятором, нельзя использовать с другим.

Этот эффект преднамеренный, чтобы защитить вас от более тонких проблем. Компиляторы различаются по многим внутренним деталям реализации C++, в том числе по тому, как размещаются экземпляры классов, как реализуется множественное наследование и как обрабатываются вызовы виртуальных функций. Если бы кодировка имени была сделана такой же, ваши программы скомпоновались бы с библиотеками, предоставленными другими компиляторами, но программы затем вылетали бы при запуске. Затем несовместимые библиотеки обнаруживаются во время компоновки, а не во время выполнения.

Изменение имен также сложнее, чем думают многие программисты. Например, как Стандарт определяет приемлемые соглашения о вызовах для всех платформ, на которых может работать C++? Должна ли RISC-система поддерживать x86 stdcall, несмотря на то, что RISC-системы обычно передают свои аргументы в регистры, а не в стек?

person Max Lybbert    schedule 12.04.2012
comment
На самом деле, двойное дополнение было стандартизировано для целых чисел, начиная с С++ 20, поэтому вам, вероятно, следует отредактировать этот пример из ответа. - person cigien; 09.02.2021