Почему большинство программ для Linux написано на C?

Почему большинство программ Linux написано на C? Почему они не написаны на C ++, который является более новым?


По этому поводу было много дискуссий. В основном причина философская. C был изобретен как простой язык для разработки систем (а не для разработки приложений). Есть много аргументов в пользу использования C ++, но примерно столько же, чтобы не использовать C ++ и придерживаться C.

В конце концов, это исторический вопрос. Большинство приложений написано на C, потому что большая часть информации о ядре написана на C. И поскольку тогда большинство вещей было написано на C, люди склонны использовать исходные языки.

В этот момент кто-то может спросить «Итак, почему ядро ​​ написано на C, а не перенесено на C ++?» . Некоторое время назад это обсуждалось на kerneltrap. Одно приятное объяснение, которое можно процитировать из этой ветки, — это ответ yoshi314 (цитируется напрямую):

это потому, что почти каждое приложение C ++ нуждается в отдельной стандартной библиотеке C ++ для работы. поэтому им придется перенести его в ядро ​​и ожидать повсюду дополнительных накладных расходов.

С ++ — более сложный язык, а это означает, что компилятор создает из него более сложный код. из-за этого обнаружить, что проблема связана с ошибкой компилятора, а не с ошибкой кода, легче в c.

также язык c более простой, и легче следить за его представлением в сборке, которое часто легко предсказать.

C ++ более универсален, но c больше подходит для низкоуровневых или встроенных вещей.


С другой стороны стороны, «большинство программ Linux» вводит в заблуждение. Взгляните на графические приложения. Python становится все более популярным, особенно в среде графического интерфейса пользователя Linux. Примерно то же самое, что происходит с Windows и .NET.


Прочитав следующее письмо от Линуса Торвальдса, создатель linux. Я не могу не думать, что ответ выше неверен. Похоже, он думает, что программисты на C ++ — плохие программисты system . И что дополнительные функции C ++ часто вызывают больше проблем в долгосрочной перспективе по сравнению с преимуществами, которые они приносят в краткосрочной перспективе. Хотя с ним можно не согласиться, трудно переоценить влияние, которое он оказал на операционную систему Linux.

http://harmful.cat-v.org/software/c++/linus

1


Я думаю, что рядом с техническими Темы об использовании C — это децентрализация системы Linux, Windows i строго централизовано: AD и т. д. Linux создается многими людьми по всему миру, и в нем нет таких инструментов, как AD, хорошо, у нас есть OpenLdap, но в Linux каждая программа работает как автономное приложение. Конечно, историческая причина — самая важная. Не представляю, кто будет заботиться о безопасности приложений объектов, если Linux будет написан на Object C ++.



Спустя столько лет мир по-прежнему работает на языке C

12 минут чтения

Многие проекты C, существующие сегодня, были начаты несколько десятилетий назад.

Разработка операционной системы UNIX началась в 1969 году, и ее код был переписан на C в 1972 году. Язык C был фактически создан для переноса кода ядра UNIX с ассемблера на язык более высокого уровня, который выполнял бы те же задачи с меньшим количеством строк кода.

Oracle разработка базы данных началась в 1977 году, и ее код был переписан с сборки на C в 1983 году. Она стала одной из самых популярных баз данных в мире.

В 1985 году была выпущена Windows 1.0. Хотя исходный код Windows не является общедоступным, было заявлено, что его ядро ​​в основном написано на C, а некоторые части находятся в сборке. Разработка ядра Linux началась в 1991 году, и оно также написано на C. В следующем году оно было выпущено под лицензией GNU и использовалось как часть операционной системы GNU. Сама операционная система GNU была создана с использованием языков программирования C и Lisp, поэтому многие из ее компонентов написаны на C.

Но программирование на C не ограничивается проектами, которые начались несколько десятилетий назад, когда еще не было. языков программирования не так много, как сегодня. Многие проекты C все еще начаты; для этого есть несколько веских причин.

Как мир работает на C?

Несмотря на преобладание языков высокого уровня, C продолжает расширять возможности мира. Ниже приведены некоторые из систем, которые используются миллионами и которые запрограммированы на языке C.

Microsoft Windows

Ядро Microsoft Windows разработано в основном на C, с некоторые детали на ассемблере. На протяжении десятилетий наиболее часто используемая операционная система в мире, занимающая около 90 процентов рынка, работает на ядре, написанном на C.

Linux

Linux — это также написан в основном на C, с некоторыми частями в сборке. Около 97 процентов из 500 самых мощных суперкомпьютеров в мире работают на ядре Linux. Он также используется во многих персональных компьютерах.

Mac

Компьютеры Mac также работают на C, поскольку ядро ​​OS X написано в основном на C. Каждая программа и драйвер на Mac, как и на компьютерах с Windows и Linux, работает на ядре C.

Mobile

Ядра iOS, Android и Windows Phone также написаны в C. Это просто мобильная адаптация существующих ядер Mac OS, Linux и Windows. Итак, смартфоны, которыми вы пользуетесь каждый день, работают на ядре C.

Базы данных

Самые популярные в мире базы данных, включая Oracle Database, MySQL, MS SQL Server и PostgreSQL, закодированы в C (первые три из них на самом деле и на C, и на C ++).

Базы данных используются во всех типах систем: финансовых, государственных, медиа, развлечений, телекоммуникаций, здравоохранения, образования, розничной торговли, социальных сети, Интернет и тому подобное.

3D-фильмы

3D-фильмы создаются с помощью приложений, которые обычно написаны на C и C ++. Эти приложения должны быть очень эффективными и быстрыми, так как они обрабатывают огромный объем данных и выполняют множество вычислений в секунду. Чем они эффективнее, тем меньше времени у художников и аниматоров уходит на создание кадров из фильма и тем больше денег экономит компания.

Встроенные системы

Представьте, что вы просыпаетесь однажды и идете за покупками. Будильник, который вас будит, скорее всего, запрограммирован на C. Затем вы используете микроволновую печь или кофеварку, чтобы приготовить завтрак. Они также являются встроенными системами и поэтому, вероятно, запрограммированы на C. Вы включаете телевизор или радио, пока завтракаете. Это также встроенные системы с питанием от C. Когда вы открываете дверь гаража с помощью пульта дистанционного управления, вы также используете встроенную систему, которая, скорее всего, запрограммирована на C.

Затем вы садитесь в свою машину . Если он имеет следующие функции, также запрограммированные на C:

  • автоматическая коробка передач
  • системы определения давления в шинах
  • датчики (кислород, температура, уровень масла и т. д.)
  • память для сидений и настроек зеркал.
  • дисплей приборной панели
  • анти- блокировка тормозов
  • автоматический контроль устойчивости
  • круиз-контроль
  • климат-контроль
  • блокировка с защитой от детей
  • вход без ключа
  • подогрев сидений
  • управление подушками безопасности

Вы попадаете в магазин , припаркуйте машину и подойдите к автомату, чтобы купить газировку. На каком языке они программировали этот торговый автомат? Наверное, С. Тогда вы что-нибудь покупаете в магазине. Кассовый аппарат тоже запрограммирован на C. А когда вы платите кредитной картой? Как вы уже догадались: устройство для чтения кредитных карт, опять же, вероятно, запрограммировано на C.

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

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

Почему до сих пор используется язык программирования C?

Там Сегодня существует множество языков программирования, которые позволяют разработчикам работать более продуктивно, чем при использовании C, для различных типов проектов. Существуют языки более высокого уровня, которые предоставляют гораздо большие встроенные библиотеки, которые упрощают работу с JSON, XML, пользовательским интерфейсом, веб-страницами, клиентскими запросами, подключениями к базе данных, манипуляциями с мультимедиа и т. Д.

Но несмотря на это что есть много причин полагать, что программирование на C будет оставаться активным в течение долгого времени.

В языках программирования не всем подходит один размер. Вот несколько причин, по которым C является непревзойденным и почти обязательным для определенных приложений.

Переносимость и эффективность

C — это почти переносимая сборка язык. Он максимально приближен к машине, хотя почти повсеместно доступен для существующих архитектур процессоров. Почти для каждой существующей архитектуры существует как минимум один компилятор C. И в настоящее время из-за высокооптимизированных двоичных файлов, генерируемых современными компиляторами, нелегко улучшить их результат с помощью рукописной сборки.

Такова его переносимость и эффективность, что «компиляторы, библиотеки и интерпретаторы других языков программирования часто реализуются на C ». Интерпретируемые языки, такие как Python, Ruby и PHP, имеют свои основные реализации, написанные на C. Он даже используется компиляторами для других языков для связи с машиной. Например, C — это промежуточный язык, лежащий в основе Eiffel и Forth. Это означает, что вместо генерации машинного кода для каждой поддерживаемой архитектуры компиляторы для этих языков просто генерируют промежуточный код C, а компилятор C обрабатывает генерацию машинного кода.

C также стал lingua franca для общения между разработчиками. Как говорит Алекс Аллен, технический менеджер Dropbox и создатель Cprogramming.com:

C — отличный язык для выражения общих идей в программировании так, как это удобно большинству людей. с. Более того, многие принципы, используемые в C — например, argc и argv для параметров командной строки, а также конструкции циклов и типы переменных — будут появляются на многих других языках, которые вы изучаете, чтобы вы могли разговаривать с людьми, даже если они не знают C, способом, который является общим для вас обоих.

Управление памятью

Доступ к произвольным адресам памяти и арифметика указателей — важная особенность, которая делает C идеальным для системного программирования (операционные системы и встроенные системы).

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

Микроконтроллер может быть спроектирован, например, так, чтобы байт в адресе памяти 0x40008000 отправлялся универсальный асинхронный приемник/передатчик (или UART, общий аппаратный компонент для связи с периферийными устройствами) каждый раз, когда бит номер 4 адреса 0x40008001 устанавливается в 1, и после того, как вы установите этот бит, он будет автоматически сброшен периферийное устройство.

Это будет код для функции C, которая отправляет байт через этот UART:

  #define UART_BYTE * (char *)  0x40008000 #define UART_SEND * (изменчивый символ *) 0x40008001 | = 0x08 void send_uart (char byte) {UART_BYTE = byte; //записываем байт по адресу 0x40008000 UART_SEND; //устанавливаем бит номер 4 адреса 0x40008001}  

Первая строка функции будет расширена до:

  * (  char *) 0x40008000 = byte;  

Эта строка сообщает компилятору интерпретировать значение 0x40008000 как указатель на char , затем разыменовать (дать значение, на которое указывает) этот указатель (с помощью самого левого оператора * ) и, наконец, присвоить значение byte для этот разыменованный указатель. Другими словами: запишите значение переменной byte по адресу памяти 0x40008000 .

Следующая строка будет расширена до:

  * (volatile char *) 0x40008001 | = 0x08;  

В этой строке мы выполняем побитовую операцию ИЛИ над значение по адресу 0x40008001 и значение 0x08 ( 00001000 в двоичном формате, т. е. 1 в бите номер 4), и сохраните результат обратно по адресу 0x40008001 . Другими словами: мы устанавливаем бит 4 байта по адресу 0x40008001. Мы также заявляем, что значение по адресу 0x40008001 является volatile . Это сообщает компилятору, что это значение может быть изменено процессами, внешними по отношению к нашему коду, поэтому компилятор не будет делать никаких предположений о значении в этом адресе после записи в него. (В этом случае этот бит сбрасывается аппаратным обеспечением UART сразу после того, как мы установили его программно.) Эта информация важна для оптимизатора компилятора. Если мы сделали это внутри цикла for , например, без указания, что значение является изменчивым, компилятор мог бы предположить, что это значение никогда не изменится после установки, и пропустить выполнение команды после первого цикла. .

Детерминированное использование ресурсов

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

Размер кода

C имеет очень маленькое время выполнения. И объем памяти для его кода меньше, чем для большинства других языков.

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

Исключения — отличный инструмент, добавленный C ++ поверх C, и, если они не запускаются и не реализованы грамотно, они практически не имеют накладных расходов на время выполнения (но при стоимость увеличения размера кода).

Давайте посмотрим на пример на C ++:

 //Объявление класса A.  Методы, определенные где-то еще;  класс А {общественность: А (); //Конструктор ~ A (); //Деструктор (вызывается, когда объект выходит за пределы области видимости или удаляется) void myMethod (); //Просто метод};//Объявление класса B.  Методы, определенные где-то еще; class B {public: B (); //Конструктор ~ B (); //Деструктор void myMethod (); //Просто метод};//Объявление класса C.  Методы, определенные где-то еще; class C {public: C (); //Конструктор ~ C (); //Деструктор void myMethod (); //Просто метод}; void myFunction () {A a; //Вызывается конструктор a.A ().  (Контрольная точка 1) {B b; //Вызов конструктора b.B ().  (Контрольная точка 2) b.myMethod (); //(Контрольная точка 3)}//вызывается деструктор b. ~ B ().  (Контрольная точка 4) {C c; //Вызывается конструктор c.C ().  (Контрольная точка 5) c.myMethod (); //(Контрольная точка 6)}//вызывается деструктор c. ~ C ().  (Контрольная точка 7) a.myMethod (); //(Контрольная точка 8)}//вызывается деструктор. ~ A ().  (Контрольная точка 9)  

Методы A , B и C классы определены где-то еще (например, в других файлах). Поэтому компилятор не может их анализировать и не может знать, будут ли они вызывать исключения. Таким образом, он должен подготовиться к обработке исключений, вызванных любым из их конструкторов, деструкторов или других вызовов методов. Деструкторы не должны выбрасывать (очень плохая практика), но пользователь может выбросить в любом случае, или они могут вызывать косвенно, вызывая некоторую функцию или метод (явно или неявно), который вызывает исключение.

вызовы в myFunction вызывают исключение, механизм раскрутки стека должен иметь возможность вызывать все деструкторы для уже созданных объектов. Одна реализация механизма разматывания стека будет использовать адрес возврата последнего вызова этой функции для проверки «номера контрольной точки» вызова, вызвавшего исключение (это простое объяснение).. Для этого используется вспомогательная автоматически сгенерированная функция (своего рода справочная таблица), которая будет использоваться для раскрутки стека в случае возникновения исключения из тела этой функции, что будет похоже на это:

 //Возможная автоматически сгенерированная функция избегает autogeneratedStackUnwindingFor_myFunction (int checkpoint) {switch (checkpoint) {//case 1 и 9: ничего не делать;  случай 3: b. ~ B ();  goto destroyA; //переходит к месту, где находится метка destroyA case 6: c. ~ C (); //также переходит к destroyA, поскольку это следующая строка destroyA://label case 2: case 4: case 5: case 7: case 8: a. ~ A ();  }}  

Если исключение выбрасывается из контрольных точек 1 и 9, ни один объект не требует уничтожения. Для контрольной точки 3 необходимо уничтожить b и a . Для контрольной точки 6 необходимо уничтожить c и a . Во всех случаях необходимо соблюдать порядок уничтожения. Для контрольных точек 2, 4, 5, 7 и 8 необходимо уничтожить только объект a .

Эта вспомогательная функция увеличивает размер кода. Это часть накладных расходов на пространство, которые C ++ добавляет к C. Многие встраиваемые приложения не могут позволить себе это дополнительное пространство. Поэтому компиляторы C ++ для встроенных систем часто имеют флаг для отключения исключений. Отключение исключений в C ++ не является бесплатным, потому что Стандартная библиотека шаблонов в значительной степени полагается на исключения для сообщения об ошибках. Использование этой модифицированной схемы без исключений требует от разработчиков C ++ дополнительной подготовки для обнаружения возможных проблем или поиска ошибок.

И мы говорим о C ++, языке, принцип которого: «Вы не плати за то, что не используешь ». Это увеличение двоичного размера ухудшается для других языков, которые добавляют дополнительные накладные расходы на другие функции, которые очень полезны, но не могут быть предоставлены встроенными системами. Хотя C не дает вам возможности использовать эти дополнительные функции, он позволяет использовать гораздо более компактный код, чем другие языки.

Причины для изучения C

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

Lingua Franca

Как уже упоминалось, C — это lingua franca для разработчиков. Многие реализации новых алгоритмов в книгах или в Интернете впервые (или только) становятся доступными на языке C их авторами. Это дает максимально возможную переносимость для реализации. Я видел, как в Интернете программисты изо всех сил пытались переписать алгоритм C для других языков программирования, потому что он или она не знали очень базовых концепций C.

Имейте в виду, что C — старый и широко распространенный язык, поэтому вы можете найти в сети все виды алгоритмов, написанных на языке C. Поэтому вам, скорее всего, будет полезно знать этот язык..

Понять машину (думать на C)

Когда мы обсуждаем с коллегами поведение определенных частей кода или определенных функций других языков, мы в конечном итоге «Говорить на C:» Эта часть передает «указатель» на объект или копирует весь объект? Может ли здесь происходить какой-то «актерский состав»? И так далее.

Мы редко обсуждаем (или думаем) об инструкциях сборки, которые выполняет часть кода при анализе поведения части кода языка высокого уровня. Вместо этого, обсуждая, что делает машина, мы довольно четко говорим (или думаем) на языке C.

Более того, если вы не можете остановиться и так подумать о том, что вы делаете, вы можете закончить программирование каким-то суеверием относительно того, как (волшебным образом) что-то делается.

Работа над множеством интересных проектов C

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

Заключение

Иллюминаты не правят миром. У программистов C есть.

Кажется, у языка программирования C нет срока годности. Его близость к оборудованию, отличная портативность и детерминированное использование ресурсов делают его идеальным для разработки на низком уровне таких вещей, как ядра операционных систем и встроенное программное обеспечение. Его универсальность, эффективность и хорошая производительность делают его отличным выбором для программного обеспечения для обработки сложных данных, такого как базы данных или 3D-анимация. Тот факт, что сегодня многие языки программирования лучше C для их предполагаемого использования, не означает, что они превосходят C во всех областях. C по-прежнему непревзойден, когда приоритетом является производительность.

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

По теме: Как узнать Языки C и C ++: полный список
Оцените статью
clickpad.ru
Добавить комментарий