Чи (C) об’єктні файли, створені за допомогою різних компіляторів, бінарні?


11

Я розумію, що компілятори C ++ не сумісні між собою. Однак я не зміг знайти нічого з цієї теми для C зокрема. Я знаю, що стандарт C залишає багато місця для компіляторів для реалізації речей, однак вони вважають за потрібне: наприклад, розмір та вирівнювання більшості (усіх?) Типів даних визначається реалізацією, крім деяких мінімальних гарантій. Тому два компілятори (або дві версії одного і того ж компілятора) можуть не погоджуватися у численних деталях.

Чи правильно я вважаю, що немає гарантії того, що два об’єктних файли, зібрані з різними компіляторами, насправді зв’язуються належним чином? Наприклад, розмір покажчиків може бути 32 біта в одному об’єктному файлі та 64 біт в іншому. Але якщо це так, чому іноді бібліотеки С поширюються у попередньо складеній формі? Чи очікується, що я буду використовувати той самий компілятор, який вони робили (наприклад, gcc), або якийсь фактичний стандарт використовувався для забезпечення бінарної сумісності? І як інші мови з інтерфейсом іноземної мови гарантують, що все буде належним чином вирівнюватися під час зв’язку з об’єктними файлами C?


Наскільки я пам'ятаю, файли об'єктів C повинні бути сумісні між собою, доки вони компільовані для однієї платформи. Об'єктний файл - це лише архів, що містить завантажений двійковий код з деякою таблицею символів, яка може використовуватися для доступу до кожного символу всередині модуля.
Джорджіо

2
гібриди можуть бути сумісними, я не думаю, що Obj гарантовано будуть
храповик урод

@Giorgo Під "тією ж платформою" ви маєте на увазі архітектуру процесора чи архітектуру процесора + ОС?
Доваль

@ratchetfreak Я був під враженням, що lib здебільшого є лише об'єднанням декількох файлів об'єктів. Це неправильно?
Доваль

Я не очікував, що об'єкти будуть сумісні в різних компіляторах.
old_timer

Відповіді:


10

Загальна відповідь - ні, компілятори мови C не сумісні між собою. Стандарт мови C не визначає будь-якого типу бінарної сумісності, і більшість авторів-компіляторів навіть не намагаються.

Мені потрібно це кваліфікувати. Об'єкти, що випромінюються компілятором С, повинні бути пов'язані з бібліотеками часу виконання, щоб створити бібліотеку, що виконується, або бібліотеку, яка може бути пов'язана із виконанням. Хоча видимі функції, надані бібліотекою виконання C, повинні бути сумісними, також існуватимуть невидимі функції, унікальні для впровадження та запобігають сумісності.

Ця відсутність сумісності поширюється і на різні версії одного компілятора. Загалом, програми та бібліотеки, зібрані зі старими та новішими версіями компілятора, не можуть бути пов’язані між собою, а ті, що компілюються з MSVC, не можуть бути пов'язані з тими, що були складені GCC.

Є конкретний і дуже корисний виняток. Кожна платформа забезпечує динамічний зв'язок ABI (Application Binary Interface) та будь-яку програму будь-якою мовою, яка може відповідати цьому ABI. Тому, як правило, можна створити DLL (в Windows) за допомогою MSVC (або чогось іншого) і викликати його з програми, складеної іншою версією MSVC або GCC, і навпаки.

У Windows є ще два ABI: збірки COM та .NET, і вони охоплюють широкий спектр мов. Таким чином, сумісність, безумовно, можлива, але сумісні вони не є.


Ступінь несумісності легко помітити, порівнюючи карти лінкерів. Для використання GNU ld -M, для MSVC link /map. Вивчіть два створені файли. Обидва матимуть імена, які ви розпізнаєте, такі як printf та main, хоча (залежно від варіантів) імена, ймовірно, можуть вводитися в різні способи. Вони також матимуть зовсім інші імена, багатьох з яких ви не впізнаєте. Для того щоб об'єктивні файли, створені різними компіляторами, були сумісні, вони повинні узгодити всі ці імена, і вони ніколи цього не роблять. Навіть різні версії одного компілятора завжди можуть це зробити.


Ця відповідь, здається, суперечить Барту ; це здається, що лише спільні бібліотеки сумісні. Чи можете ви пояснити, чому не видимі функції, характерні для впровадження бібліотеки часу виконання C, перешкоджають сумісності? Ви також говорите, що "об'єкти, що випромінюються компілятором С, повинні бути пов'язані з бібліотеками часу виконання, щоб створити або виконану бібліотеку, або бібліотеку, що може бути пов'язана із виконанням" - а як статичні бібліотеки?
Доваль

Як сказав Барт, сумісні лише бібліотеки з ABI. Спільні бібліотеки (на Unix) - це один із видів ABI, є й інші. Напишіть HelloWorld.c, компілюйте його з MSVC та gcc, порівняйте карти, і ви побачите, наскільки вони відрізняються. "Бібліотеки часу виконання" означають основні функції підтримки, на які автоматично посилається кожен компілятор C / C ++, які можуть бути статично або динамічно пов'язані. Прочитайте карту чи вихідний код CRT, щоб побачити їх.
david.pfx

Я не знаю, що означає порівняння карт, тому я буду трохи більш конкретним: чи можна на практиці припустити, що всі компілятори для даної архітектури процесора та комбінації ОС сумісні? Наприклад, у мене є main.c, який я компілюю з gcc та mylibrary.c, який я компілюю з clang, обидва націлені на Linux x64. Якщо припустити, що це основна ОС (Linux, Mac, Windows), чи можна впевнено припустити, що вона буде працювати незалежно від того, що два компілятори?
Доваль

1
Вкрай малоймовірно, перевірте карту посилання кланг. Див. Редагування.
david.pfx

17

Те, що ви шукаєте, називається ABI (Application Binary Interface).

Мова C не визначає ABI, тому в цьому сенсі дійсно немає гарантії, що файли C, складені з різних компіляторів, будуть працювати один з одним.

З іншого боку, на більшості платформ ОС визначає ABI для взаємодії з ним і всіх компіляторів, націлених на те, що сім'я ОС і процесорів також використовує той самий ABI для взаємодії з компонентами, які не є ОС. Так, на практиці об'єкти C, створені різними компіляторами, можуть працювати один з одним.


Що має сенс. Я вважаю, що спільні бібліотеки також відповідають ABI ОС?
Доваль

3
@Doval Особливо загальнодоступні бібліотеки, їх потрібно називати зовнішнім світом.
toasted_flakes
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.