Чому люди використовують С, якщо він такий небезпечний?


132

Я розглядаю питання навчання C.

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

Під небезпечним я маю на увазі покажчики та інші подібні речі.

Як і запитання про переповнення стека Чому функція get настільки небезпечна, що її не слід використовувати? . Чому програмісти не просто використовують Java чи Python чи іншу мову, що склалася, наприклад Visual Basic?


152
Чому кухарі використовують ножі, якщо ними можна користуватися «небезпечно»?
oerkelens

78
З великою силою приходить велика відповідальність.
Пітер Б

10
Джо Удар, багато понтифікати?
Меттью Джеймса Бріггса

4
Тому що "Назад у той день", коли C став мовою вибору, від нас, як очікували, ми зможемо впоратися з подібними справами, тому що нам довелося. Інтерпретовані або байтовані мови були надто повільними, оскільки процесори дня були набагато повільнішими. (Сьогодні я можу придбати настільний ПК низького класу з багатоядерним процесором 2+ ГГц і 4 ГБ пам’яті від Dell за 279 доларів. У вас немає ІДЕА, як це абсолютно неймовірно виглядає у хлопця, як я, для якого 4 МГц ПК з 640 кілобайт пам’яті було блаженством ...). Ознайомтеся - Закон Мура переміг. Гра. Понад!
Боб Джарвіс

6
@Bob Jarvis: Гра не закінчена. Якщо ви думаєте, що ваш 2 + ГГц, 4 Гб ПК - або, з цього приводу, ваш кластер із декількох сотень ПК на 4 ГГц із найновішими графічними процесорами CUDA або будь-яким іншим - досить швидкий, ви просто не працюєте над досить сильними проблемами :-)
jamesqf

Відповіді:


246
  1. C передує багатьом іншим мовам, про які ви думаєте. Багато з того, що ми знаємо зараз про те, як зробити програмування "безпечнішим", походить із досвіду з такими мовами, як C.

  2. Багато хто з більш безпечних мов, які з'явилися з моменту C, для досягнення своїх цілей покладаються на більший час виконання, складніший набір функцій та / або віртуальну машину. В результаті, C залишився чимось "найнижчим загальним знаменником" серед усіх популярних / основних мов.

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

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

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

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

  4. Навіть у межах C ми дізналися багато правил та рекомендацій, які, як правило, різко скорочують кількість підступних помилок, які з’являються на практиці. Взагалі неможливо отримати стандарт для застосування цих правил заднім числом, оскільки це порушить занадто багато існуючого коду, але звичайно використовувати попередження компілятора, лінери та інші інструменти статичного аналізу для виявлення таких проблем, які легко запобігаються. Підмножина програм C, які передають ці інструменти з літаючими кольорами, вже набагато безпечніше, ніж "просто C", і будь-який грамотний програміст на C сьогодні буде використовувати деякі з них.


Крім того , ви ніколи не будете зробити затемнений конкурс Java як розважальним , як заплутаний конкурс C .


7
"найнижчий загальний знаменник" звучить зневажливо. Я б сказав, що на відміну від багатьох набагато важчих мов, C не вимагає тонни зайвого багажу, який вам не потрібен, і дає вам блискавичну базу, на якій можна реалізувати потрібні вам речі. Це ви мали на увазі?
підкреслити_9

9
"Неможливо насправді мати одне без іншого.": Насправді намагаються зробити багато нових мов (Rust, Nim, D, ...). Це в основному зводиться до відповідності "безпечного" підмножини мови з парою "небезпечних" примітивів, коли цей рівень контролю є абсолютно необхідним. Однак усі вони ґрунтуються на знаннях, накопичених із C та C ++, тому, можливо, слід сказати, що в той час, коли C і C ++ були розроблені, ви не могли мати одне без іншого, а нині є мова, яка намагається розділити їх. їх "небезпечні" шматочки, але вони ще не наздогнали.
Матьє М.

6
1) не є дійсним пунктом! C взяв риси Algol 68, що є "безпечною" мовою в цьому сенсі; тому автори знали про такі мови. Інші моменти чудові.
reinierpost

4
@MatthieuM. Можливо, ви також хочете поглянути на Microsoft Research. За останнє десятиліття-два вони створили кілька керованих ОС, включаючи такі, які швидші (абсолютно випадково - головна мета більшості цих дослідницьких ОС - безпека, а не швидкість), ніж еквівалентна некерована ОС для певних реальних навантажень. . Швидкість роботи здебільшого пояснюється обмеженнями безпеки - статична та динамічна перевірка виконуваних файлів дозволяє здійснити оптимізацію, яка недоступна в некерованому коді. Тут є дещо подивитися,
загалом

3
@Luaan: Midori виглядає так приголомшливо; Я завжди з нетерпінням чекаю статей у блозі Джо.
Матьє М.

41

По-перше, C - це мова програмування систем. Так, наприклад, якщо ви пишете віртуальну машину Java або інтерпретатор Python, вам знадобиться система програмування мови для їх запису.

По-друге, C забезпечує ефективність таких мов, як Java та Python. Зазвичай для високоефективних обчислень на Java та Python будуть використовуватися бібліотеки, написані на високопродуктивній мові, такі як C, щоб робити важкі підйоми.

По-третє, C має набагато менший слід, ніж такі мови, як Java та Python. Це робить його корисним для вбудованих систем, які можуть не мати ресурсів, необхідних для підтримки великих середовищ виконання та вимог пам'яті таких мов, як Java та Python.


"Мова програмування систем" - це мова, придатна для побудови промислово-міцних систем; Як вони стоять, Java та Python не є системами мов програмування. "Саме те, що робить мовою програмування систем", не виходить за межі цього питання, але мова програмування систем повинна забезпечити підтримку роботи з базовою платформою.

З іншого боку (у відповідь на коментарі), мова програмування систем не потребує самостійного розміщення. Це питання прийшов тому , що первинний питання задає «чому люди використовують C», то перший коментар запитав «чому б вам потрібна мова , як C» , коли у вас є PyPy, і я помітив , що PyPy робить фактично використовувати C. Таким чином, це спочатку стосувався питання, але, на жаль (і заплутано) "самохостинг" насправді не має відношення до цієї відповіді. Вибачте, що я виховував це.

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


19
"якщо ви пишете віртуальну машину Java або інтерпретатор Python, вам знадобиться система програмування мови для їх запису." А? Як ви пояснюєте PyPy? Навіщо вам потрібна така мова, як C, щоб написати компілятор чи перекладач або віртуальну машину?
Вінсент Савард

10
Я вважаю, що ви заявляли, що вам потрібна мова системного програмування, щоб написати віртуальну машину Java або інтерпретатор Python, коли ви сказали, "якщо ви пишете віртуальну машину Java або інтерпретатор Python, для запису їх вам знадобиться системна мова програмування". Якщо PyPy вас не влаштовує, ви також можете шукати будь-якого перекладача чи компілятора, написаного на Haskell. Або дійсно, просто додайте посилання, що підтверджують вашу претензію.
Вінсент Савард

16
Навіть якщо це черепашки аж донизу, щось на зразок PyPy не могло б існувати без інтерпретатора Python, написаного якоюсь іншою мовою.
Blrfl

18
@Birfl Але це насправді не дуже багато. C не могла бути написана без компілятора збірки, і ви не можете написати збірку без обладнання, яке це реалізує.
садок

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

30

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

"Я розглядаю питання навчання C"

Чому? Ви хочете робити типи речей, які зазвичай використовуються на сьогодні (наприклад, драйвери пристроїв, віртуальних машин, ігрових двигунів, медіатеки, вбудовані системи, ядра ОС)?

Якщо так, то так, то обов'язково вивчіть C або C ++ залежно від того, хто з вас цікавиться. Чи хочете ви це вивчити, щоб ви глибше зрозуміли, що робить ваша мова на високому рівні?

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

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


2
Чудова робота, відповідаючи на те, що здається справжнім питанням! Чудовий спосіб оцінити C / C ++ та "безпечніші" мови для всіх, що вони є насправді, - спробувати написати щось на зразок простого механізму роботи з базами даних. Ви отримаєте гарне відчуття щодо кожного з підходів, які ви спробуєте, і побачите, куди це веде вас. Ви побачите, що відчуває себе природним у будь-якому, і ви знайдете, де природний підхід не вдається (наприклад, "серіалізувати" необроблені дані в C дуже просто - просто запишіть дані; але результат не є портативним, так що може бути обмеженим). Розуміння безпеки складне, тому що з більшості питань може бути важко зіткнутися.
Луаан

1
@Luaan саме, навчитися копіювати рядок за допомогою покажчиків дає вам ідею, навчитися робити це безпечно - це інший рівень, а залежно від цілей, можливо, непотрібний.
Джаред Сміт

2
Це насправді не було питанням. Але це було корисним для вирішення питання. Я вирішив це зробити. Я готовий дізнатися більше про внутрішню роботу всього, на чому будується. І я просто люблю програмування. Таким чином я сподіваюся краще зрозуміти внутрішню роботу комп’ютерів. Це просто для розваги.
Трістан

10
Я не згоден з останнім реченням. Дізнайтеся, як це зробити правильно, перш ніж розвивати шкідливі звички.
glglgl

2
@glglgl IDK, якщо я читаю (або пишу) фрагмент JavaScript в Інтернеті, я роблю це з розумінням того, що його не готово до виробництва: він не матиме обробку винятків, це може бути O (n ^ 2) тощо. що необхідно, щоб отримати точку впоперек. Все це необхідно для виробничого коду. Чому це різне? Я можу написати наївний С для власного зведення, розуміючи інтелектуально, що якби я хотів його викласти там, мені потрібно було б зробити ще багато роботи.
Джаред Сміт

14

Це ВЕЛИЧЕЗЕ запитання з тоннами відповідей, але коротка версія полягає в тому, що кожна мова програмування спеціалізована для різних ситуацій. Наприклад, JavaScript для Інтернету, C для речей низького рівня, C # для будь-якого Windows тощо. Це допомагає дізнатися, що ви хочете зробити, як тільки знаєте програмування, щоб вирішити, яку мову програмування вибрати.

Щоб вирішити вашу останню точку, чому C / C ++ над Java / Python, вона часто скорочується. Я роблю ігри, і Java / C # недавно досягають швидкостей, які досить хороші для запуску ігор. Зрештою, якщо ви хочете, щоб ваша гра працювала зі швидкістю 60 кадрів в секунду, і ви хочете, щоб ваша гра робила багато (рендерінг особливо дорогий), тоді вам потрібен код, щоб запустити якомога швидше. Python / Java / C # / Багато інших працюють на "інтерпретаторах", додатковому шарі програмного забезпечення, яке обробляє всі нудні речі, які не має C / C ++, наприклад управління пам'яттю та збирання сміття. Цей додатковий наклад сповільнює роботу, тому майже кожну велику гру, яку ви бачите, було зроблено (за останні 10 років у будь-якому випадку) на C або C ++. Є винятки: ігровий движок Unity використовує C # *, а Minecraft використовує Java, але вони є винятком, а не правилом. Загалом,

* Навіть Unity - це не все C #, величезні фрагменти - це C ++, і ви просто використовуєте C # для свого ігрового коду.

EDIT Щоб відповісти на деякі коментарі, які з’явилися після того, як я опублікував це: Можливо, я занадто сильно спрощував, я просто давав загальну картину. З програмуванням відповідь ніколи не є простою. Є інтерпретатори для C, Javascript може працювати за межами браузера, а C # може працювати майже будь-що завдяки Mono. Різні мови програмування спеціалізуються на різних областях, але десь програміст, певно, придумав, як змусити будь-яку мову працювати в будь-якому контексті. Оскільки ОП, здається, мало знає програмування (припущення з мого боку, вибачте, якщо я помиляюсь), я намагався зробити свою відповідь простою.

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

Щоб відповісти на мій коментар "просто досягнення швидкості", так, велика частина швидкості C # відбувається завдяки кращому апаратному забезпеченню, але, оскільки .NET Framework та компілятор C # покращилися, там відбулися деякі прискорення.

Про коментар "ігри написані тією ж мовою, що і двигун", це залежить. Деякі є, але багато написано гібридом мов. Unreal може робити UnrealScript і C ++, Unity робить C # Javascript і Boo, багато інших двигунів, написаних на C або C ++, використовують Python або Lua як мови скриптування. Там немає простої відповіді.

І тільки тому, що мене клопочуть, щоб прочитати "кому все одно, якщо ваша гра працює зі швидкістю 200 кадрів в секунду або 120 кадрів в секунду", якщо гра працює швидше 60 кадрів в секунду, ви, мабуть, витрачаєте час на процесор, оскільки середній монітор навіть не оновлює це швидко. Деякі вищі кінці та новіші, але це не стандартно (все ж ...).

Щодо зауваження "ігнорування десятиліть технологій", я все ще в моїх ранніх 20-х роках, тому, коли я екстраполюю назад, я в основному повторюю те, що мені сказали старші та досвідченіші програмісти. Очевидно, що ви будете оскаржуватись на такому сайті, але це варто розглянути.


4
" C # для нічого Windows " - О, це така помилка. І ти навіть наводиш приклад. Єдність. AFAIK Це не написано, він надає API C #, оскільки мова приємна для адаптації. Це дійсно добре розроблено. І мені більше подобається c ++, але кредит слід надавати там, де належить. Можливо, ви змішали C # з .NET? Вони вішають разом досить часто.
luk32

2
"Навіть Єдність - це не все C #, величезні фрагменти - це C ++" І? Ігри в Unity часто широко використовують C # і вже досить давно існують. Припустити, що C # "нещодавно досягає швидкості" або потребує більше контексту, або ризикує бути сліпим для цього десятиліття технологій.
NPSF3000

2
Майже кожна велика гра була написана мовою двигуна, який вона використовувала: обсяг роботи, який потребував би дублювання, був настільки великий, що жоден інший технічний розгляд навіть не варто брати до уваги. Візуалізація дійсно дорога, але сьогодні це все написано шейдерами, а мова логічного циклу не має значення.
Пітер Тейлор

2
C # завжди був компільований JIT (на відміну від Java, де ваш коментар правильний), і він цілком здатний мати дуже схожі швидкості виконання на C ++ з початку, якщо ви знали, що ви робите. Це 2003 рік - не те, що я б вважав останнім часом. Сировинна швидкість не є основною проблемою для ігор (особливо з програмованими шейдерами на графічному процесорі). Є й інші речі, які часом роблять такі мови, як C # більш-менш популярними. Дві основні проблеми - API (які сильно орієнтовані на С, і взаємозв'язок може бути дорогим) та GC (здебільшого для питань затримки, а не пропускної здатності).
Луаан

1
@gbjbaanb Це не лише швидкість процесорів - велика справа в тому, що C ++ і C мали десятиліття, щоб удосконалити свої компілятори та час виконання, тоді як Java почала з нуля (насамперед розроблялася як багатоплатформна платформа). По мірі вдосконалення VM (наприклад, перехід від інтерпретатора до компілятора JIT, поліпшення GC ...), так само зросла продуктивність програм Java. Багато що ще є на C / C ++ - у підході "сподіваємось, що нічого не зламається" - уникаючи безлічі перевірок, які вважаються "непотрібними". Але це все ще величезна свиня пам’яті - насправді покращення використання процесора часто означало погіршення продуктивності пам’яті :)
Luaan

13

Смішно, що ви стверджуєте, що C є небезпечнішим, оскільки "він має покажчики". Справедливо навпаки: у Java та C # є практично лише вказівники (для неродніх типів). Найпоширеніша помилка в Java - це, мабуть, виключення Null Pointer (див. Https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare ). Друга найпоширеніша помилка - це, мабуть, приховані посилання на невикористані об'єкти (наприклад, закриті діалоги не видаляються), які, таким чином, не можуть бути випущені, що призводить до довготривалих програм з постійно зростаючим друком на нозі пам'яті.

Є два основні механізми, які роблять C # та Java більш безпечними та безпечнішими двома різними способами:

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

Останні C ++ 'розумні покажчики полегшують цю роботу програмістам.

  • Java і C # компілюються в проміжний код, який інтерпретується / виконується детальним часом виконання. Це додає рівня безпеки, оскільки час запуску може виявити незаконні дії програми. Навіть якщо програма кодується невпевнено (що можливо обома мовами), відповідний час виконання теоретично запобігає "прориву" в систему.
    Час виконання не захищає, наприклад, від спроб перевищення буфера, але теоретично не допускає використання таких програм. З C і C ++, навпаки, програміст повинен надійно кодувати, щоб запобігти подвигам. Зазвичай цього не досягається відразу, але потрібні огляди та повторення.

Варто зауважити, хоча складний час роботи також є ризиком для безпеки. Мені здається, що Oracle оновлює JVM кожні пару тижнів через нововиявлені проблеми безпеки. Звичайно, набагато складніше перевірити СВМ, ніж одну програму.

Отже, безпека детального часу запуску неоднозначна і до певної міри обманлива: Ваша середня програма C може, з оглядами та повтореннями, бути досить безпечною. Ваша середня програма Java настільки ж безпечна, як і JVM; тобто не дуже. Ніколи.

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


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

1
Крім того, stackoverflow.com/questions/57483/… - було б точніше сказати, що на java є "практично лише посилання".
Сем Дюфель

4
Я бачив, що всілякі цікаві помилки є результатом спроб уникнути явних покажчиків. Зазвичай основним питанням є плутанина між копією та посиланням. У C, якщо я передаю вам вказівник на щось, ви знаєте, що його зміна вплине на оригінал. Деякі спроби уникнути покажчиків приховують цю відмінність, що призводить до лабіринту глибоких копій, дрібних копій та загальної плутанини.
Арлі Стівенс

Стверджувати, що JVM компанії Oracle відсмоктує (з точки зору крововиливу експлуатаційні вразливі місця безпеки), і тому час експлуатації керованих мов в цілому викликає більше проблем щодо безпеки, ніж використання керованої мови, це означає, що сказати, що Adobe Flash жахливий як джерело невпевненості, і програма, яка чи відтворення відео та анімації з веб-сайту по суті повинно бути смішно небезпечним. Не всі умови виконання Java майже такі ж погані, як і у Oracle / Sun 1990-х років, у вітчизняному стилі JVM, і не всі керовані мови - це Java. (Ну, очевидно.)
здебільшогоінформували

@halfinformed Well; Я говорив, що програма є настільки ж безпечною, як і час її виконання, і що "ваша середня" (читайте: невелика-іш) програма може бути спрощена, ніж будь-яка велика програма виконання, як інтерпретатор байтового коду. Це твердження видається незаперечним. Будь-яка окрема програма або певний час виконання є більш-менш безпечною, ніж інша, залежить від їхньої складності та дизайну, кодування та якості обслуговування. Наприклад, я б не сказав, що sendmail є більш безпечним, ніж Java VM Oracle; але qmail може бути.
Пітер А. Шнайдер

10

Оскільки "безпека" коштує швидкості, "безпечніші" мови працюють з меншою швидкістю.

Ви запитуєте, чому використовуєте "небезпечну" мову, як C або C ++, чи хтось напише вам драйвер відео чи подібне в Python чи Java тощо? І подивіться, як ви ставитесь до "безпеки" :)

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


20
Загалом це неправда, що безпека коштує швидкості . Більш безпечні доступні мови роблять більшість перевірок під час компіляції. O'Caml, Ada, Haskell, Rust все не відстають далеко від C за середньою швидкістю виконання. Те, що вони зазвичай роблять, - це значні витрати на розмір програми, ефективність пам’яті, затримку та, очевидно, час збирання. І так, у них є труднощі з наближеними до металу металами. Але це насправді не питання швидкості.
близько

6
Крім того, C не робить те, що, на вашу думку, робить. С - абстрактна машина . Це не дає вам прямого доступу до чогось - це гарна річ. Ви навіть не можете подивитися на сучасну збірку, щоб побачити, скільки C ховається від вас - сучасна збірка (наприклад, TASM) вважалася б мовою високого рівня ще при розробці C. Я був би дуже радий, якби хтось написав драйвери на "безпечній" мові, дякую - це цілком допомогло б уникнути безлічі цих BSOD і заморозок, не кажучи вже про дірки в безпеці :) І найголовніше, що існують системні мови, які набагато безпечніші ніж C.
Луань

3
@Wintermute Ви дуже хочете шукати Іржа, перш ніж коментувати, як функції безпеки обов'язково коштують швидкості. Чорт, система типу низького рівня фактично гальмує багато дуже корисних оптимізацій, які компілятори могли б зробити в іншому випадку (особливо якщо врахувати, що майже жоден великий проект c не вдається уникнути, щоб десь не порушити суворий псевдонім ).
Во

7
@Wintermute Так, міф про те, що ви не можете зробити C / C ++ будь-яким безпечнішим без впровадження накладних витрат, є дуже стійким, тому я ставлюся до цього досить серйозно (є деякі сфери, де це, безумовно, вірно [перевірка меж]). Тепер чому іржа не має більшого поширення? Історія та складність. Іржа все ще відносно нова, і багато найбільших систем, написаних на C, існували ще до того, як Руст коли-небудь був винайдений - ви не збираєтеся переписувати мільйон LOC новою мовою, навіть якщо це було набагато безпечніше. Також кожен програміст та їх собака знають С, Руст? Успіхів знайти достатньо людей.
Voo

3
@Voo Собаки роблять C? ... не дивно, що я бачив так багато поганого коду там ... j / k Точка, взята про Рюста (я щойно завантажив і встановив її, тож у вас може бути ще один перетворювач, щоб додати) BTW з повагою щоб Раст робив це правильно ... Я міг би зробити те саме збільшення для "D" :)
Wintermut3

9

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

В основному майже всі мови мають інтерфейс API для C.

Простий приклад, спробуйте створити загальний додаток для Linux / IOS / Android / Windows. Окрім усіх інструментів, які знаходяться там, те, що ми закінчили, робив основну бібліотеку на C, а потім змінював графічний інтерфейс для кожного середовища, тобто:

  • IOS: ObjectiveC може використовувати C-бібліотеки вроджене
  • Android: Java + JNI
  • Linux / Windows / MacOS: За допомогою GTK / .Net ви можете використовувати рідні бібліотеки. Якщо ви використовуєте Python, Perl, Ruby, кожен з них має вбудовані інтерфейси API. (Ява знову з JNI).

Мої два центи,


Однією з причин, що я люблю використовувати, скажімо, PHP, є те, що майже всі її бібліотеки справді написані на С - на щастя, або PHP було б нестерпно повільним :) PHP чудово писати неохайний код без побоювання робити що-небудь «небезпечне» (і тому я, як правило, пишу набагато більше PHP-коду, ніж будь-що інше - мені подобається неохайний код!: D), але приємно знати, що під великою кількістю цих викликів функцій є хороший ol 'trusty Бібліотеки C, щоб підвищити її ефективність ;-) На противагу цьому, писати неохайний код на C - це велика ні-ні ...
Gwyneth Llewelyn

7

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

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

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

Розглянемо щось на кшталт:

int hey(int x)
{
   printf("%d", x);
   return x*10000;
}
void wow(int x)
{
  if (x < 1000000)
    printf("QUACK!");
  hey(x);    
}

Гіпермодерна (але модна) теорія компілятора підказує, що компілятор повинен вивести "QUACK!" безумовно, оскільки в будь-якому випадку, коли умова була помилковою, програма в кінцевому підсумку посилатиметься на невизначену поведінку, виконуючи множення, результат якого все одно буде ігноруватися. Оскільки Стандарт дозволить компілятору робити все, що йому подобається в такому випадку, він дозволяє компілятору вивести "QUACK!".

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


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

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

2
@ robertbristow-johnson: Насправді Стандарт досить чітко говорить про те, що, наприклад int arr[5][[5], спроба доступу arr[0][5]призведе до не визначеної поведінки. Таке правило дає можливість компілятору, якому надано щось подібне arr[1][0]=3; arr[0][i]=6; arr[1][0]++;до висновку, що arr[1][0]буде рівним 4, без огляду на значення i.
supercat

2
@ robertbristow-johnson: Навіть якщо компілятор виділяє масиви в структурі послідовно без пропусків, це не гарантує, що індексація одного з масивів гарантовано вплине на іншу. Дивіться godbolt.org/g/Avt3KW для прикладу того, як gcc буде ставитися до такого коду.
supercat

1
@ robertbristow-johnson: Я прокоментував збори, щоб пояснити, що це робить. Компілятор бачить, що код зберігає 1 в s-> arr2 [0], а потім збільшує s-> arr2 [0], тому gcc поєднує ці дві операції, маючи код, просто зберігаючи значення 2, не враховуючи можливості запису втручається до s-> arr1 [i] може вплинути на значення s-> arr1 [0] (оскільки, згідно зі Стандартом, він не може).
supercat

5

Історичні причини. Мені часто не доводиться писати абсолютно новий код, в основному я намагаюся підтримувати і розширювати старі речі, які працюють десятиліттями. Я просто щасливий, що це C, а не Фортран.

Я можу роздратуватися, коли якийсь студент каже: "але чому ти робиш це жахливе Х, коли ти міг би робити Y?". Ну, X - це робота, яку я отримав, і вона дуже добре оплачує рахунки. Я робив Y з нагоди, і це було весело, але Х - це те, що робить більшість із нас.


5

Що таке "небезпечно"?

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

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

Крім того, "небезпечний" залежить від контексту: що ви намагаєтесь зробити, і які види ризиків вас турбують?

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

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

Хоча C і C ++ спеціально не розроблені для цього типу додатків, вони широко застосовуються для вбудованого та критичного для безпеки програмного забезпечення з кількох причин. Основні властивості примітки - це контроль над управлінням пам’яттю (що дозволяє уникнути необхідності збирання сміття, наприклад), прості, добре налагоджені основні бібліотеки часу роботи та підтримка зрілих інструментів. Багато вбудованих ланцюжків інструментів розробки, що застосовуються сьогодні, вперше були розроблені у 1980-х та 1990-х роках, коли це була сучасна технологія і походить з культури, яка була поширеною в той час, тому ці інструменти залишаються популярними для такого роду робіт.

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


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

5

Щоб додати до існуючих відповідей, все добре і добре, що ви збираєтесь вибрати Python або PHP для свого проекту через їх відносну безпеку. Але комусь належить реалізувати ці мови, і коли вони це зроблять, вони, ймовірно, зроблять це в C. (Або, ну, щось подібне.)

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


2

Дозвольте перефразувати ваше запитання:

Я розглядаю навчання [інструмент].

Але чому люди використовують [інструмент] (або [пов'язаний інструмент]), якщо [вони] можуть бути використані "небезпечно"?

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

Наприклад, якщо вам потрібно помістити циліндричний отвір діаметром 6 мм, глибиною 5 см у дерев’яний брус, свердло є набагато кращим інструментом, ніж аналізатор LALR. Якщо ви знаєте, що це за два інструменти, ви знаєте, який є правильним інструментом. Якщо ви вже знаєте, як використовувати дриль, вуаля !, отвір.

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


Ця відповідь є причиною, чому питання викидаються як "в першу чергу на основі думки". Не кажіть, що C має свої переваги, кажіть, що вони є!
reinierpost

1

Я розглядаю питання навчання С

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

Інакше кажучи, якби C був набором деревообробних інструментів, швидше за все, це:

  • молоток
  • нігті
  • Ручні пилки
  • ручна дриль
  • блок шліфувальної машини
  • зубило (можливо)

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

C ++ - це колекція електроінструментів у вашому місцевому магазині обладнання.

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

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

Тому що деякі люди не хочуть меблів від IKEA. =)

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

Більш конкретно, C має такий набір функцій, які роблять його бажаним для багатьох програмістів:

  • Швидкість - Через відносну простоту та оптимізацію компілятора протягом багатьох років, це спочатку дуже швидко. Крім того, багато людей з'ясували багато ярликів до конкретних цілей під час використання мови, що робить її потенційно ще швидшою.
  • Розмір - З аналогічних причин, що вказані для швидкості, програми C можна зробити дуже маленькими (як з точки зору виконуваного розміру, так і з використанням пам'яті), що бажано для середовищ з обмеженою пам'яттю (тобто вбудованої або мобільної).
  • Сумісність - C існує вже давно, і кожен має інструменти та бібліотеки для цього. Мова сама по собі теж не вибаглива - вона очікує, що процесор виконує вказівки та пам'ять для зберігання матеріалів, і це стосується цього.

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

Чому програмісти не просто використовують Java чи Python чи іншу мову, що склалася, наприклад Visual Basic?

Ефективність (а іноді і схеми управління пам'яттю, які неможливо реалізувати без відносно прямого доступу до пам'яті).

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

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

Що стосується скриптованих мов і подібних помилок, вам доведеться наполегливо працювати, щоб мови, що вимагають, щоб вторинні програми запускалися так само ефективно, як і C (або будь-яка складена мова). Додавання ввімкненого інтерпретатора по суті дає можливість зменшити швидкість виконання та збільшити використання пам'яті, оскільки ви додаєте іншу програму до суміші. Ефективність ваших програм залежить як від ефективності цієї вторинної програми, так і від того, наскільки добре (погано =) ви написали свій початковий програмний код. Не кажучи вже про те, що ваша програма часто повністю покладається на другу програму навіть для виконання. Та друга програма чомусь не існує в певній системі? Код не йде.

Насправді введення будь-якого "зайвого" потенційно уповільнює або ускладнює ваш код. Мовами "без страшних покажчиків" ви завжди чекаєте, коли інші біти коду очистяться за вами, або іншим чином винайдете "безпечні" способи вчинити, тому що ваша програма все ще робить ті самі операції з доступу до пам'яті, що і для інших покажчики. Ви просто не той, хто цим обробляє (так що ви не можете f * ck it up, genius = P).

Під небезпечним я маю на увазі покажчики та інші подібні речі. [...] Як запитання про переповнення стека Чому функція get настільки небезпечна, що її не слід використовувати?

Відповідно до прийнятої відповіді:

"Він залишався офіційною частиною мови аж до стандарту ISO C 1999 року, але офіційно був видалений стандартом 2011 року. Більшість програм C все ще підтримують його, але принаймні gcc видає попередження для будь-якого коду, який використовує його."

Думка, що оскільки щось можна зробити мовою, це треба зробити, є дурним. Мови мають вади, які виправляються. З міркувань сумісності зі старішим кодом цю конструкцію все ще можна використовувати. Але нічого (ймовірно) не змушує програміста використовувати get (), і фактично ця команда була по суті замінена більш безпечними альтернативами.

Більш того, проблема з get () не є проблемою вказівника сама по собі. Це проблема з командою, яка не обов'язково знає, як безпечно використовувати пам'ять. В абстрактному сенсі це все питання вказівника - читання та написання матеріалів, яких ви не повинні. Це не проблема з покажчиками; це проблема з реалізацією вказівника.

Для уточнення покажчики не є небезпечними, поки ви випадково не отримаєте доступ до місця пам'яті, до якого ви не збиралися. І навіть тоді це не гарантує, що ваш комп'ютер розтане або вибухне. У більшості випадків ваша програма просто перестане функціонувати (правильно).

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

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

Підсумовуючи це, є дуже мало причин боятися вказівника, якщо він безпечно використовується. Просто знайдіть підказку з версії Стіва "Мисливець на крокодилів" Ірвіна - Саунд-Парк, - не обмінюйтесь, стирчавши великий палець у купінах крокусів .


2
Я не згоден з пропозицією вивчити C ++ замість C. Писати хороший C ++ важче, ніж писати хороший C, а читати C ++ набагато складніше, ніж читати C. Отже, крива навчання C ++ набагато крутіша. "C ++ - це супер набір C" Це більш-менш схоже на те, що казати, що черевики - це суперкомплект тапочок. Вони мають різні переваги та використання, і кожен має функції, які не має інший.
мартінкунев

"Писати хороший C ++ важче, ніж писати хороший C" - Абсолютно. =) "[R] eading C ++ набагато складніше, ніж читання C" - Будь-яке розширене програмування, ймовірно, не відрізняється від магії ;-) Мої два центи - це те, що це набагато більше, ніж програміст, залежний від мови, хоча C ++ нічого не робить для того, щоб допомогти собі в цій категорії. "Отже, крива навчання C ++ набагато крутіша". - Зрештою, так. В короткостроковій перспективі, менше (на мою думку). Анекдотично, більшість основних мовних курсів на C та C ++, ймовірно, охоплюють приблизно однакові загальні типи матеріалів, крім класів для C ++.
Anaksunaman

2
"Вони мають різні переваги та використання, і кожен має функції, які інші не мають". - Як вже згадувалося, "Немає конкретної причини, щоб не вивчати С [.]" C - це чудова мова, і я дотримуюся цього. Якщо це відповідає ОП чи комусь іншому, я повністю підтримую його вивчення. =)
Анаксунаман

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

1

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

Іноді ви виявите, що проблема добре піддається тому, що включено в бібліотеки Java за замовчуванням, і в такому випадку ви можете обрати Java для цього. В інших випадках можливо, що вам потрібно зробити щось у Windows, що набагато простіше в .NET під час виконання .NET, тому ви можете використовувати C # або VB. Може бути графічний інструмент або скрипт команд, який вирішує вашу проблему, тоді ви можете використовувати їх. Можливо, вам потрібно написати програму GUI на декількох платформах, Java може бути варіантом, враховуючи включені бібліотеки в JDK, але знову ж таки, одна цільова платформа може бракувати JRE, тому, можливо, ви замість цього вибираєте C та SDL (або подібний).

C займає важливе місце в цьому наборі інструментів, оскільки він загальний, малий і швидкий, а також збирається в машинний код. Він також підтримується на будь-якій платформі під сонцем (проте не без перекомпіляції).

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

Будь ласка, відволіктися від розуму: "Я програміст X" (X = C, C ++, Java тощо)

Просто використовуйте "Я програміст".

Програміст вирішує проблеми та розробляє алгоритми, інструктуючи машини виконувати навантаження. Кінець історії. Це не має значення для мови. Ваша найважливіша майстерність - це вирішення проблем та логічне розбиття структурованих проблем, навички / вибір мови ВЖЕ є вторинними та / або наслідком характеру проблеми.

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


0

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


0

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

Не має значення, якщо ви використовуєте C ++ у такому випадку. Ви все ще будете static_castsрозповсюджувати весь код, щоб відкидати void*покажчики, і все ще працюєте з бітами та байтами, і просто матимете більше клопотів, пов’язаних із дотриманням системи типів у цьому контексті, ніж C, у якій набагато простіша система типу, де ви вільні до memcpyбітів і байтів навколо, не турбуючись про бульдозування над типовою системою.

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

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

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

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

Це легко сприймати як належне. Я пам’ятаю пост у фейсбуці, коли хтось вказував, наскільки можливо створити 3D-гру з Python, що означає, що мови низького рівня застарівають, і це, безумовно, гра пристойного вигляду. Але Python здійснював виклики високого рівня в бібліотеки, реалізовані на C, щоб виконати всі важкі роботи. Ви не можете робити Unreal Engine 4, просто здійснюючи дзвінки високого рівня в існуючі бібліотеки. Unreal Engine 4 єбібліотека. Він робив усілякі речі, які ніколи не існували в інших бібліотеках та двигунах, від освітлення до навіть його вузлової системи креслення, і як він може збирати та запускати код на льоту. Якщо ви хочете внести інновації на низькому рівні двигуна / ядра / ядра, то вам доведеться отримати низький рівень. Якби всі ігрові розробники перейшли на безпечні мови високого рівня, не було б Unreal Engine 5, або 6, або 7. Ймовірно, люди все ще користуються Unreal Engine 4 десятиліття пізніше, тому що ви не можете внести інновації на необхідний рівень. з двигуном наступного покоління, просто здійснюючи дзвінки високого рівня в старий.

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