Чому операційні системи роблять матеріали низького рівня в C та C ++? Чому б не просто C ++?


20

На сторінці Wikipedia для Windows зазначено, що Windows написано в Асамблеї для завантажувача і перемикача завдань, а C і C ++ для підпрограм ядра.

IIRC, ви можете викликати функції C ++ з extern "C"'d блоку. Я можу отримати використання C для функцій ядра, тому чисті програми C можуть використовувати їх (як printfі такі), але якщо їх просто можна загорнути в extern "C "блок, то чому код у C?


10
Ви бачили різні "Навіщо використовувати C, коли є C ++?" питання тут? Це не обов'язково дублікат будь-якого з них, але вони пов'язані між собою.

1
"ви можете викликати функції C ++ із зовнішнього блоку" C "" d як C ++ "Ви маєте на увазі, що можете викликати функції C ...?
Код-Гуру

@ Code-Guru ні, тому що єдиною різницею між експортованими функціями C і C ++ є прикраса імен і в C ++, додавання thisзмінної
Cole Johnson

2
Накиньте виняток у ISR та подивіться, що станеться
Джеймс

Ще одне питання проти С ++.
Мачадо

Відповіді:


31

Це здебільшого з історичних причин. Деякі частини ядра Windows були спочатку написані на мові C, оскільки 1983 рік, коли три десятиліття тому, коли Windows 1.0 був розв'язаний , C ++ ледь вийшов. Тепер ці C-бібліотеки залишаться там "назавжди", тому що Microsoft зробила зворотну сумісність точкою продажу, а переписання сумісної з помилками версії C-частин на C ++ вимагає неабияких зусиль, щоб не отримати ефективної користі.


+1, я думаю, що це найбільш реальна відповідь (окрім того, що можуть бути деякі розробники ядер Windows, яким просто не подобається C ++ або не довіряють компіляторам C ++ для цих матеріалів низького рівня). Подивіться, наприклад, тут stackoverflow.com/questions/520068/… , чому ядро ​​Linux написано в C.
Doc Brown

@ back2dos - Хоча їх код C не буде викинутий, це не означає, що він буде використовуватися або не оновлюватися. Я гарантую вам, що існує щонайменше один метод, який робить щось, що було спочатку написано і містилося в бібліотеці C, яка була перенесена бібліотекою C ++ у Windows 8
Ramhound

8
Мені важко повірити, що в будь-якому нещодавному випуску Windows є код Windows 1.0. Windows ME - це останній випуск Windows, який не базувався на базі коду Windows NT. І навіть це було значною мірою замінено новим ядром RT (яке, наскільки я розумію, не дуже обіцяє на шляху зворотної порівнянності).
TMN

@TMN: Аргумент, ймовірно, вірний - я майже впевнений, що на шляху від Win 1.0 до теперішнього часу було багато бібліотек, написаних на C, які все ще є частиною поточної бази коду Win8, і ніхто в MS не бачить жодної вигода переписати їх у C ++.
Док Браун

1
Навряд чи існує код, який так чи інакше спілкується з ядром Windows. В основному, це роблять тільки водії. Зазвичай програми спілкуються з API Win32 або, можливо, з POSIX.
MSalters

24

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

C - це невелика мова в тому сенсі, що специфікація (відносно) коротка. C ++ величезна, і це заниження. Це може не мати великого значення для програміста (хоча, я думаю, це і є), але вкрай важливо, якщо ви хочете зробити офіційну перевірку . Крім того, є створені інструменти для аналізу коду С, які можуть допомогти запобігти помилкам тощо.

І це дуже важливо у вбудованому програмному забезпеченні, де вартість розгорнутої помилки надзвичайно висока порівняно з рештою галузі (порівняйте Web, де ви можете негайно застосувати виправлення до всіх користувачів). Не кажучи вже про критичні для місії програмні засоби та медичні матеріали.

Були спроби витіснити C зі свого домінуючого місця в програмуванні низького рівня з мовами, які в цьому навіть кращі, як BitC, але вони досі не мали успіху.


4
+1 Для згадування найважливішого програмного забезпечення в чистому С (наприклад, ПС). Однак у медичному програмному забезпеченні також використовується C ++ (замість офіційної перевірки використовується розширене тестування, що було б надзвичайно важко в C ++).
Джорджіо

1
Також C має досить успішне безпечне підмножина MISRA-C. Є еквіваленти для C ++, але вони фактично не є галузевим стандартом (поки що). Тенденція критично важливих для безпеки програм полягає в тому, що бібліотеки та компілятори також будуть змушені використовувати безпечну підмножину на зразок MISRA. Перезапис MISRA-C ++ сумісної версії всієї стандартної бібліотеки C ++, швидше за все, буде кошмаром.

2
@Lundin Вказівки MISRA не є безпечним підмножиною - у вас все ще є необроблені покажчики та більшість інших функцій, які роблять C небезпечним - вони в основному зосереджуються на тому, щоб не використовувати або документувати особливості поведінки впровадження.
Піт Кіркхем

@PeteKirkham MISRA-C зловить усі найкласичніші помилки вказівника та застосує статичний аналіз. Галузеві стандарти безпеки (IEC 61508 та ін.), Очевидно, затверджують MISRA-C як безпечну підмножину C. Немає багатьох інших корисних альтернатив для критично важливих програм, якщо ви не вибрали SPARK Ada, мову, яку мало хто знає, з обмеженим інструментом підтримка.

2
Це було б обрано як найкращу відповідь, оскільки це правильно. Інші, хто припускає, що С використовується лише з історичних причин, істеричний сам по собі.
Роб

15
  1. Час виконання C набагато менше.
  2. Переклад C ++ на конструкції нижчого рівня менш прозорий, ніж у C. (Див. Посилання та vtables, для двох швидких прикладів)
  3. З, як правило, має стійкий ABI. З ++ зазвичай немає. Це означає, що за мінімального мінімуму інтерфейс системного виклику повинен бути стилем C. Крім того, якщо вам потрібні будь-які динамічні модулі, наявність послідовного ABI дуже допомагає.

+1 для (2) та (3). Я не переконаний у (1).
Томас Едінг

7
@Thomas Eding: Час виконання C ++ складається з часу виконання C, а також функцій C ++, таких як винятки, RTTI та інший розподільник пам'яті. YMMV щодо того, чи вважається це набагато більшим. (А тут є стандартна бібліотека ...)
wnoise

Ах, я забув про винятки та нові / видалення пулів. RTTI я ніколи не використовую: D
Томас Едінг

11

Причини не технічні. Трохи складання неминуче, але вони не змушені користуватися випадковими С, вони хочуть . Моя компанія використовує власне власне ядро, написане майже повністю на C ++, але нам не потрібно підтримувати інтерфейс C до ядра, як і більшість інших, тому що наше вбудоване ядро ​​монолітно компілюється з нашими програмами C ++. Якщо у вас є інтерфейс C, то простіше написати код інтерфейсу на C, навіть якщо це можливо використовувати extern "C"для запису його на C ++.

Навіть ми маємо дефіцит файлів С, здебільшого завдяки сторонній коду. Сторонній код низького рівня майже завжди надається в C, тому що набагато простіше включити код C у додаток C ++, ніж навпаки.


6

Розробники ядра часто є тими людьми, які відчувають себе щасливішими, коли з джерела відразу видно, що насправді робить код.

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

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

Але API ядра не може бути API C ++, він повинен бути мовно-агностичним API, тому більшість приємних речей у C ++ не можуть бути безпосередньо використані в цьому інтерфейсі. Крім того, ядро ​​насправді не поділяється на "бібліотеку" та "додаток" частини, розроблені самостійно, з більшими зусиллями логічно збираючись в одній бібліотеці, щоб спростити створення маси додатків.

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

Коротше кажучи, хоча ви, звичайно, можете писати будь-яку програму C, включаючи ядро ​​як C ++, більшість потужностей C ++ недостатньо використовується в ядрі. І багато хто стверджує, що засоби програмування повинні заважати вам робити те, чого не слід робити. C ++ не хотів.


+1. Як розробник ядра, моє "велике правило" полягає в тому, що якщо ви не можете легко оцінити "торкаються рядки кеша", то мова, яку ви використовуєте, приносить більше шкоди, ніж користі.
Брендан

Уточнення: для ядер ви повинні припустити, що процесор проводить більшу частину свого часу в просторі користувача, а код ядра використовується епізодично (наприклад, коли користувальницький простір викликає API ядра або відбувається переривання); а це означає, що ви повинні припустити "холодний кеш". Для сучасних процесорів (де оперативна пам'ять повільна відносно швидкості процесора) кеш-пам'ять і помилки TLB є дорогими, тому (у поєднанні з очікуванням "холодного кеша") метрика "торкаються ліній кеша" стає надзвичайно важливим показником для продуктивності та / або масштабованості.
Брендан

5

Bjarne Stroustrup, в інтерв'ю в липні 1999 року :

Жодна з цих мов не була докорінно різною або кардинально кращою, ніж інші сучасні мови. Однак вони були досить хорошими і користувались удачею та соціальними факторами


2
Ласкаво просимо, Девід. Цитуючи або цитуючи, корисно надати посилання (додано!)
Андрій

3

C за своєю конструкцією дуже низький рівень мови. Це в одному кроці від асемблера; знаючи чіпсет, на який ви орієнтуєтесь, ви можете, маючи невеликі знання, вручну "скласти" C в ASM. Цей тип "близької до металу" мови є ключовим для високих рівнів оптимізації (для продуктивності, ефективності пам'яті тощо). Однак, оскільки це так близько до металу, з цією мовою ви не отримаєте багато; це процедурна, не об'єктно-орієнтована мова, і, отже, робота з такими конструкціями передбачає багато кодового коду для створення та використання багатозначних конструкцій у пам'яті.

C ++ - це "C one better", додаючи ряд зручних у використанні функцій, таких як динамічне розподілення пам'яті, вбудована маршалізація структури, велика бібліотека заздалегідь визначеного коду тощо за рахунок певних втрат ефективності (все ще набагато краще ніж середовища керованого виконання). Для середнього кодера переваги значно переважають недоліки в областях кодової бази, які не потребують анально-ретентивного контролю розподілу пам'яті тощо.

Поєднання двох - досить традиційне; ви використовуєте C для написання найбільш критичних для продуктивності пам'яті областей бази даних, з якими потім можна працювати більш абстраговано, використовуючи виклики методів з коду C ++, які можуть бути більш елегантно організовані та розроблені, ніж виконавці uber , uber-oogly оптимізований код C.


2
Щодо ефективності, я повторюсь: (1) Люди з С ++ скажуть вам, що це фігня. (2) Я кажу, що я не бачу причин, щоб це було так, і я хотів би конкретних прикладів. Не приклади того, як легко написати менш ефективний код, але приклади того, як бути настільки ж ефективним, як і C, вимагає зайвої неподобства.

3
Визначте «потворне»; Я кодую в C # на життя, і кожного разу, коли я бачу приклади коду C ++ у StackOverflow, я чіпляюсь за те, наскільки чіткою вважається нормальна при використанні мови щодня. Коли я кодував C ++ назад, коли я часто бачив код C і стискався; типи будови ручної упаковки, розрахунки покажчика виконання для ручних стрибків, вбудований ASM ... yuck. Деякі люди сповіщають про втрату знань низького рівня серед програмістів Java / .NET; Я вважаю це величезним благом для продуктивності.
KeithS

1
Ви не відповідали на моє запитання;) Під "потворним" я маю на увазі "потворне за стандартами гуру С ++". Іншими словами, приклади, коли не можна використовувати "сучасний C ++" та бути настільки ж ефективним, як C.

2
Це може бути правдою (я, чесно кажучи, не знаю). Щодо розробки ядра (та кількох інших полів), ми не говоримо про середніх програмістів.

3
Люди забувають, що C -> C ++ - це континуум. Занадто часто ці аргументи порівнюють хороший, сучасний C ++ з C. Ви можете взяти програму C і зрівняти її з компілятором C ++ за порівняно короткий час, і він запуститься рівно так швидко. Якщо сучасна функція C ++ "занадто повільна", не використовуйте її. Це може включати навіть такі речі iostream. "Занадто повільно" ніколи не є хорошим приводом для використання C над C ++.
Gort the Robot

1

Можливо, з C ви витрачаєте більшу частину часу на роздуми про проблему, про яку йдеться, і про те, як кодувати рішення. У мові C ++ ви думаєте про C ++ та його безліч особливостей, функцій та незрозумілого синтаксису.

Крім того, у багатьох магазинах C ++ ваш код контролюється "поліцією моди", яка захоплена останнім набором моделей дизайну, або останніми нерозбірливими вимовами великого бога Струструпа. Гарний код стає більш цінним, ніж робочий код, пошук використання останнього набору шаблонів Boost захоплюється більше, ніж пошук робочого рішення для бізнесу.

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


0

Можливо, що частини C не дуже добре переносяться на компілятор C ++, який використовується для частин C ++. Можливо, код C чутливий з компілятором C таким чином, що переривається з компілятором C ++.

Якщо у вас є якісний компілятор C ++, майже немає підстав змішувати C і C ++ в проекті. Майже.

Однією з причин було те, що ваш проект ділиться кодом C з іншими проектами, код не компілюється як C ++, і ви не хочете підтримувати вилку C ++ цього коду.


-1

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


-2

Існують різні рівні вбудованих платформ, що використовують С як мову програмування (звичайно, це ваша свобода використовувати мову складання в будь-який час)

Для "рівня" я кажу про рівень внутрішнього SRAM та ROM для системи.

Ці платформи іноді обмежені ресурсами (наприклад, деякі 8051 платформи мають лише 128 байт користувача SRAM).

Підтримувати динамічний розподіл пам'яті з таким невеликим об'ємом для оперативної пам’яті безглуздо. (новий / видалити) або навіть malloc у C.

Одним з головних удосконалень від C до C ++ є об'єктно-орієнтована парадигма. C ++ підходить для програмного забезпечення з більшим відбитком пам’яті

але не у вбудованій прошивці, яка має обмеження розміру до 32 КБ. (наприклад, у 16-бітній платформі MCU)

Немає необхідності мати компілятор C ++, який, як правило, складніше, ніж компілятор C. (принаймні провайдери SDK не будуть це робити).

Насправді я навряд чи можу знайти компілятор C ++ на 32-бітній платформі ARM7.

Це просто не варто складності

У деяких 8051 (8 біт): 1 Мб ROM, 128B оперативної пам’яті

TI MSP430 (16 біт): 32 КБ ПЗУ, 4 КБ ОЗУ

32-розрядний процесор Cortex ™ -M3 CPU ST Microelectronics ARM (STM32F103T4): 16 або 32 Кбайт флеш-пам'яті, 6 або 10 Кбайт SRAM


2
Це не має нічого нового в інших відповідях, вже розміщених тут.
Martijn Pieters

32-розрядний компілятор C ++ для ARM? Якщо хотіли, ви можете самостійно скласти LLVM з джерела після декількох модифікацій, щоб отримати компілятор C ++ для iOS.
Коул Джонсон

-4

Я бачу пару можливих причин:

  • C трохи ефективніше порівняно з еквівалентом C ++.
  • Деякі бібліотеки, якими вони користуються, написані на С.
  • Вони використовують деякі частини ядра Linux, які написані на С.

Відредаговано: Як виявляється, третій аргумент не відповідає дійсності (див. Коментарі).


5
(1) С ++ люди б просили відрізнятися. І об'єктивно я не бачу причин, щоб це було так. (2) C ++ може просто зателефонувати в код C (у цьому вся суть зворотної сумісності та extern "C").

1
Якщо MS використовує деякі частини ядра Linux, а ядро ​​Linux - це GPL, чи не означає це, що Windows також повинна бути GPL?
TomJ

1
@TomJ насправді саме тому вони були змушені пожертвувати пару тисяч рядків також для Linux. + Чому, на вашу думку, вони підтримують розробку Linux?
Pijusn

2
@Pius Його справа в цьому (і він має рацію AFAIK), якби код GPL був пов'язаний з ядром Windows, все ядро ​​повинно бути GPL'd (за умови, що не існує окремої угоди з власниками авторських прав).

@delnan, не впевнений у деталях. Я не юрист, тому не можу це коментувати. Але пару років тому з цього приводу був невеликий скандал. Не впевнений, але я думаю, що я, можливо, був мережевим модулем у всіх шалених речах.
Піджун

-4

Тому що C, мабуть, краща мова, ніж C ++. А тому, що частина коду була написана ще до того, як C ++ став популярним, і люди не мали причин замінити його.

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


C ++ очікує динамічних бібліотек? А що таке динамічна пам'ять?

4
-1 для [stuff] that C++ expects. Чому C ++ використовує більше купи, ніж C? Чому для C ++ потрібно більше dll, ніж C? Просто НЕ ІСТИНА
Thomas Eding

1
Виправлення: Ви втрачаєте бібліотеки, записані на C ++. Тож повернемося до квадрата 1, якщо ви використовуєте C ++ або C. Навіщо обмежувати себе функціональністю C, якщо ви можете використовувати шаблони, класи, деструктори, const та всілякі інші товари.
Томас Едінг

6
Що? Шаблони, винятки, об’єкти (включаючи конструктори, деструктори, перевантажені оператори, тепер рухаються конструкції, і - практично? - все інше) тощо, працюють добре, незалежно від того, звідки знаходиться пам'ять (стек, статична пам’ять, власний пул чи інше) . Стандартні контейнери використовують розподіл кучи за замовчуванням, але їх алокатори можуть бути налаштовані, і хлопці ядра все одно пишуть власні колекції та управління пам'яттю. -1

2
FYI: Я зняв свій голос, тому що зараз не думаю, що ваша відповідь є активно шкідливою, але я також не вважаю її особливо корисною або проникливою.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.