Есть ли у C стандартный ABI? - PullRequest
28 голосов
/ 20 декабря 2010

Из обсуждения где-то еще :

C ++ не имеет стандартного ABI

Но также не имеет C, верно?

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

Что вы думаете по этому поводу?

Ответы [ 8 ]

30 голосов
/ 20 декабря 2010

C не определяет ABI. Фактически, он наклоняется назад, чтобы избежать определения ABI. Те люди, которые, как и я, которые посвятили большую часть своей жизни программированию на C на 16/32/64 битных архитектурах с 8-битными байтами, арифметическим и плоским адресным пространством 2-х дополнений, обычно будут весьма удивлены чтению сложного языка текущий стандарт C.

Например, прочитайте материал об указателях. Стандарт не говорит ничего такого простого: «указатель - это адрес», поскольку в нем делается предположение о ABI. В частности, он позволяет указателям находиться в разных адресных пространствах и иметь различную ширину.

ABI - это отображение модели исполнения языка на конкретную комбинацию машина / операционная система / компилятор. Нет смысла определять его в спецификации языка, потому что это рискует исключить реализации C на некоторых архитектурах.

14 голосов
/ 20 декабря 2010

C не имеет стандартного ABI в принципе, но на практике это редко имеет значение: вы делаете то, что делает ваш поставщик ОС.

Возьмем соглашения о вызовах в Windows x86, например: Windows API использует так называемое «стандартное» соглашение о вызовах (stdcall). Таким образом, любой компилятор, который хочет взаимодействовать с ОС, должен реализовать это. Тем не менее, stdcall не поддерживает все возможности языка C90 (например, вызов функций без прототипов, функции с переменным числом аргументов). Поскольку Microsoft предоставила компилятор C, было необходимо второе соглашение о вызовах, называемое C 'соглашение о вызовах (cdecl). Большинство компиляторов C в Windows используют это как соглашение о вызовах по умолчанию и, следовательно, являются совместимыми.

В принципе, то же самое могло бы случиться с C ++, но поскольку ABI C ++ (включая соглашение о вызовах) обязательно намного сложнее, производители компиляторов не договорились об одном ABI, но все же могли бы взаимодействовать, возвращаясь к extern "C".

5 голосов
/ 20 декабря 2010

ABI, даже для C, имеет части, которые не зависят от платформы, части, которые зависят от процессора (какие регистры должны быть сохранены, которые используются для передачи параметров, ...) и части, которые зависят от ОС (более или менее те же факторы, что и для процессора, так как некоторые варианты выбора не навязываются архитектурой, а являются результатом компромиссов, плюс некоторые ОС имеют независимое от языка понятие исключения, и поэтому компилятор для любого языка должен генерировать правильноечто бы справиться с этим, обработка потоков может также навязывать вещи в ABI - если регистр указывает на TLS, вы не можете использовать его для того, что хотите).

Теоретически, каждый компилятор может иметь свойсобственный ABI.Но обычно для пары процессор / ОС ABI устанавливается поставщиком ОС, который часто также предоставляет компилятор C и общие библиотеки, которые используют ABI и конкуренты, которые предпочитают быть совместимыми.(Я не удивлюсь, если есть исключения для некоторых ОС, для которых C не является основным языком программирования.)

Но поставщик ОС может переключить ABI по той или иной причине (новые версии процессоров).может иметь функции, которые вы хотите использовать в ABI для одного - например, некоторые просили 32-битный ABI для x86_64, позволяющий использовать все регистры).На этапе миграции, который может длиться очень долго, вам, возможно, придется работать с двумя ABI.

4 голосов
/ 10 апреля 2013

С тоже не так, верно?
Верно

На любой данной платформе в значительной степени . Он не был бы полезен в качестве языка общения между языками, если бы его не было.
В значительной степени может относиться к специфическим для архитектуры значениям по умолчанию, выбранным поставщиками компиляторов C, адаптированными для других языков. Таким образом, если компилятор Keil ARM C будет использовать порядок слева направо и порядок байтов для передачи аргументов и некоторый предопределенный регистр для возвращаемого значения, тогда extern «C» из других компиляторов примет совместимость с такой схемой.

Хотя такое соглашение может считаться частью ABI, в отличие от контекста управляемого выполнения, такого как песочница для браузера JVM, сам по себе он далеко не полный стандарт ABI.

4 голосов
/ 20 декабря 2010

ABI для C зависит от платформы - он охватывает такие вопросы, как распределение регистров и соглашения о вызовах, которые, очевидно, специфичны для конкретного процессора.Вот несколько примеров:

x86 имеет много соглашений о вызовах, какие расширения под Windows объявляют, какое из них используется.ABI платформы для встраиваемых Linux-систем также со временем менялись, что приводило к несовместимому пользовательскому пространству.См. Некоторую историю порта ARM Linux здесь , которая показывает проблемы при переходе на более новый ABI.

3 голосов
/ 20 декабря 2010

Хотя было предпринято несколько попыток определить один ABI для данной архитектуры для нескольких операционных систем (особенно для i386 в Unix Systems), усилия не увенчались таким успехом.Вместо этого операционные системы обычно определяют свои собственные ABI ...

Цитирование ... Системное программирование Linux стр. 4.

1 голос
/ 20 декабря 2010

C не имеет стандартного ABI. Это легко иллюстрируется всеми соглашениями о вызовах (cdecl, fastcall и stdcall), которые используются там. У каждого свой ABI.

0 голосов
/ 10 января 2017

До появления стандарта C89 компиляторы C для многих платформ использовали, по сути, один и тот же ABI, за исключением различий в размерах данных.Для машин, у которых стек растет вниз, код, вызывающий функцию, помещает аргументы в стек в порядке справа налево , а затем вызывает функцию (отправляя адрес возврата в процессе).Вызываемая функция оставила бы свои аргументы в стеке, и вызывающая сторона на досуге скорректировала бы указатель стека, чтобы удалить их [или, на некоторых архитектурах, могла бы корректировать сложенные значения на месте].Хотя <stdarg.h> лишало большинство программ необходимости полагаться на это соглашение, оно продолжало использоваться в течение многих лет, поскольку оно было простым и работало довольно хорошо.Хотя не было «официального» документа, устанавливающего этот стандарт как кроссплатформенный «стандарт», большинство компиляторов, нацеленных на машины с растущими вниз стеками, работали таким образом, что приводило к более высокому уровню согласованности, чем сегодня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...