Подтвердить что ты не робот

Имеет ли C стандартный ABI?

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

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

Но и не C, правильно?

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

Что вы берете на себя?

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

Ответ 4

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

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

Ответ 5

и не C, правильно?
Правильно

На любой данной платформе это в значительной степени. Это было бы не полезно, как lingua franca для межязыковой коммуникации, если ему не хватало одного.
Довольно многое может относиться к специфическим по архитектуре значениям по умолчанию, выбранным поставщиками компилятора C, адаптируемыми на других языках. Поэтому, если компилятор Keil ARM C будет использовать упорядочивание и стеки параметров слева направо, чтобы передать аргументы и некоторый предопределенный регистр для возвращаемого значения, тогда extern" C" из других компиляторов будет предполагать совместимость с такой схемой.

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

Ответ 6

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

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

Ответ 7

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

Ответ 8

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