Я рассматриваю возможность изучения C.
Но почему люди используют C (или C ++), если его можно использовать «опасно»?
Под опасным я имею в виду указатели и другие подобные вещи.
Как и вопрос переполнения стека. Почему функция gets настолько опасна, что ее не следует использовать? , Почему программисты не просто используют Java, Python или другой скомпилированный язык, такой как Visual Basic?
Ответы:
C предшествует многим другим языкам, о которых вы думаете. Многое из того, что мы теперь знаем о том, как сделать программирование «более безопасным», получено из опыта работы с такими языками, как C.
Многие из более безопасных языков, появившихся после C, для достижения своих целей полагаются на большее время выполнения, более сложный набор функций и / или виртуальную машину. В результате C остается чем-то вроде «наименьшего общего знаменателя» среди всех популярных / основных языков.
C - намного более простой в реализации язык, потому что он относительно мал и с большей вероятностью будет работать адекватно даже в самой слабой среде, поэтому многие встроенные системы, которым необходимо разрабатывать свои собственные компиляторы и другие инструменты, с большей вероятностью смогут обеспечить функциональный компилятор для C.
Поскольку C такой маленький и простой, другие языки программирования, как правило, взаимодействуют друг с другом, используя C-подобный API. Вероятно, это главная причина, по которой С никогда не умрет, даже если большинство из нас когда-либо взаимодействуют с ним только через оболочки.
Многие из «безопасных» языков, которые пытаются улучшить C и C ++, не пытаются быть «системными языками», которые дают вам почти полный контроль над использованием памяти и поведением во время выполнения вашей программы. Несмотря на то, что все больше приложений в наши дни просто не нуждаются в таком уровне контроля, всегда будет небольшое количество случаев, когда это необходимо (особенно внутри виртуальных машин и браузеров, которые реализуют все эти красивые, безопасные языки для остальные).
Сегодня существует несколько языков системного программирования (Rust, Nim, D, ...), которые безопаснее, чем C или C ++. Они имеют преимущества задним числом и понимают, что в большинстве случаев такой точный контроль не требуется, поэтому предлагают в целом безопасный интерфейс с несколькими небезопасными перехватчиками / режимами, которые можно переключать, когда это действительно необходимо.
Даже в C мы изучили много правил и руководств, которые, как правило, резко сокращают количество коварных ошибок, которые обнаруживаются на практике. Как правило, невозможно заставить стандарт принудительно применять эти правила задним числом, потому что это может нарушить слишком большой существующий код, но обычно используются предупреждения компилятора, линтеры и другие инструменты статического анализа для обнаружения такого рода легко предотвратимых проблем. Подмножество программ на C, которые передают эти инструменты с летающими цветами, уже намного безопаснее, чем «просто C», и любой компетентный программист на C сегодня будет использовать некоторые из них.
Кроме того, вы никогда не сделаете запутанный Java-конкурс таким же интересным, как и запутанный C-конкурс .
источник
Во-первых, C - язык системного программирования. Так, например, если вы пишете виртуальную машину Java или интерпретатор Python, вам понадобится язык системного программирования для их записи.
Во-вторых, C обеспечивает производительность, которой нет у таких языков, как Java и Python. Как правило, высокопроизводительные вычисления в Java и Python используют библиотеки, написанные на высокопроизводительном языке, таком как C, для выполнения тяжелой работы.
В-третьих, C имеет гораздо меньшую площадь, чем такие языки, как Java и Python. Это делает его пригодным для встраиваемых систем, которые могут не иметь ресурсов, необходимых для поддержки больших сред выполнения и требований к памяти таких языков, как Java и Python.
«Язык системного программирования» - это язык, подходящий для создания систем промышленного уровня; Java и Python не являются языками системного программирования. «Именно то, что делает язык системного программирования», выходит за рамки этого вопроса, но язык системного программирования должен обеспечивать поддержку работы с базовой платформой.
С другой стороны (в ответ на комментарии) язык системного программирования не обязательно должен быть хостом. Этот вопрос пришел потому , что первоначальный вопрос задает «почему люди используют C», то первый комментарий спросил «почему бы вам нужен язык , как C» , когда у вас есть PyPy, и я заметил , что PyPy делает фактически использовать C. Таким образом, это Первоначально был актуален для вопроса, но, к сожалению (и сбивает с толку) «самодостаточность» на самом деле не имеет отношения к этому ответу. Извини, что поднял это.
Итак, подведем итог: Java и Python не подходят для системного программирования не потому, что их основные реализации интерпретируются, или потому, что встроенные реализации не являются самостоятельными, а потому, что они не обеспечивают необходимую поддержку для работы с базовой платформой.
источник
Извините, что добавил еще один ответ, но я не думаю, что какой-либо из существующих ответов напрямую относится к вашему первому предложению с указанием:
Почему? Вы хотите сделать то, что C обычно используется сегодня (например, драйверы устройств, виртуальные машины, игровые движки, библиотеки мультимедиа, встроенные системы, ядра ОС)?
Если да, то да, обязательно изучите C или C ++ в зависимости от того, кого из вас интересует. Хотите ли вы выучить это, чтобы у вас было более глубокое понимание того, что делает ваш язык высокого уровня?
Затем вы продолжаете упоминать проблемы безопасности. Вам не обязательно глубокое понимание безопасного C, чтобы сделать последнее, точно так же, как пример кода на языке более высокого уровня может дать вам суть, не будучи готовым к работе.
Напишите немного кода на C, чтобы понять суть. Затем положите его обратно на полку. Не беспокойтесь о безопасности, если вы не хотите писать производственный C-код.
источник
Это ОГРОМНЫЙ вопрос с множеством ответов, но вкратце, каждый язык программирования специализирован для различных ситуаций. Например, 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 # для своего игрового кода.
РЕДАКТИРОВАТЬ Чтобы ответить на некоторые комментарии, которые появились после того, как я опубликовал это: Возможно, я слишком сильно упрощал, я просто давал общую картину. С программированием ответ никогда не бывает простым. Есть интерпретаторы для 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 кадров в секунду, вы, вероятно, тратите время процессора, так как средний монитор даже не обновляет это быстрый. Некоторые более высокие и более новые делают, но это не стандартно (пока ...).
Что касается замечания «игнорировать десятилетия технологий», мне все еще за двадцать, поэтому, когда я экстраполирую задом наперед, я в основном повторяю то, что говорили мне более старые и более опытные программисты. Очевидно, что это будет оспариваться на сайте, как это, но это стоит рассмотреть.
источник
Забавно, что вы утверждаете, что C небезопасен, потому что «у него есть указатели». Верно обратное: Java и C # имеют практически только указатели (для не нативных типов). Наиболее распространенной ошибкой в Java, вероятно, является исключение нулевого указателя (см. Https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare ). Второй наиболее распространенной ошибкой, вероятно, являются скрытые ссылки на неиспользуемые объекты (например, закрытые диалоги не удаляются), которые поэтому не могут быть освобождены, что приводит к длительным программам с постоянно растущим отпечатком памяти.
Существует два основных механизма, которые делают C # и Java более безопасными и безопасными двумя различными способами:
Последние умные указатели C ++ облегчают эту работу для программистов.
Время выполнения не защищает, например, от попыток переполнения буфера, но теоретически не позволяет использовать такие программы. В отличие от C и C ++, программист должен надежно кодировать, чтобы предотвратить эксплойты. Это обычно не достигается сразу, но нуждается в обзорах и итерациях.
Стоит отметить, однако, что сложное время выполнения также является угрозой безопасности. Мне кажется, что Oracle обновляет JVM каждые пару недель из-за недавно обнаруженных проблем безопасности. Конечно, гораздо сложнее проверить JVM, чем отдельную программу.
Поэтому безопасность тщательно продуманного времени выполнения неоднозначна и в некоторой степени обманчива: ваша средняя программа на C может быть сделана с помощью проверок и итераций достаточно безопасной. Ваша обычная Java-программа настолько безопасна, насколько JVM; то есть не совсем. Никогда.
Статья, на
gets()
которую вы ссылаетесь, отражает исторические библиотечные решения, которые сегодня будут приняты по-другому, а не основной язык.источник
Поскольку «безопасность» стоит скорости, «безопасные» языки работают медленнее.
Вы спрашиваете, зачем использовать «опасный» язык, такой как C или C ++, кто-то напишет вам видеодрайвер или тому подобное на Python или Java и т. Д. И посмотрите, что вы думаете о «безопасности» :)
Если серьезно, то вы должны быть как можно ближе к основной памяти машины, чтобы иметь возможность манипулировать пикселями, регистрами и т. Д. ... Java или Python не могут сделать это с любым типом быстродействия, достаточным для производительности ... C и C ++ оба позволяют вам делать это с помощью указателей и тому подобного ...
источник
Помимо всего вышеперечисленного, есть также один довольно распространенный вариант использования, который использует C как общую библиотеку для других языков.
В основном, почти все языки имеют интерфейс API для C.
Простой пример, попробуйте создать общее приложение для Linux / IOS / Android / Windows. Помимо всех имеющихся инструментов, мы создали библиотеку ядра на C, а затем изменили графический интерфейс для каждой среды, а именно:
Мои два цента,
источник
Фундаментальная трудность с C состоит в том, что имя используется для описания ряда диалектов с идентичным синтаксисом, но очень различной семантикой. Некоторые диалекты намного безопаснее других.
В C, изначально разработанном Деннисом Ритчи, операторы C обычно отображаются в машинные инструкции предсказуемым образом. Поскольку C мог работать на процессорах, которые вели себя по-разному, когда происходили такие вещи, как подписанное арифметическое переполнение, программист, который не знал, как поведет себя машина в случае арифметического переполнения, не знал бы, какой код C, работающий на этой машине, тоже будет себя вести, но если машина, как было известно, ведет себя определенным образом (например, обход без компиляции с двумя дополнительными компонентами), то реализации на этой машине обычно делают то же самое. Одна из причин, по которой С приобрел репутацию быстрой, заключается в том, что в тех случаях, когда программисты знали, что естественное поведение платформы в сценариях с граничными случаями соответствует их потребностям, программисту или компилятору не нужно было писать код для генерации таких сценариев. ,
К сожалению, авторы компиляторов придерживаются мнения, что, поскольку Стандарт не предъявляет никаких требований к тому, что реализации должны делать в таких случаях (слабость, которая должна была обеспечить аппаратные реализации, которые могут вести себя непредсказуемо), компиляторы должны свободно генерировать код, который отрицает законы времени и причинности.
Рассмотрим что-то вроде:
Гиперсовременная (но модная) теория компилятора предполагает, что компилятор должен выводить «QUACK!» безусловно, поскольку в любом случае, когда условие было ложным, программа в конечном итоге вызывала неопределенное поведение, выполняющее умножение, результат которого все равно будет игнорироваться. Поскольку стандарт позволяет компилятору делать все, что ему нравится, в таком случае он позволяет компилятору выводить «QUACK!».
В то время как C раньше был безопаснее ассемблера, при использовании гиперсовременных компиляторов верно обратное. В языке ассемблера целочисленное переполнение может привести к тому, что вычисления приведут к бессмысленному результату, но на большинстве платформ это будет иметь степень его влияния. Если результаты в конечном итоге будут проигнорированы, переполнение не будет иметь значения. В гиперсовременном C, однако, даже то, что обычно было бы «доброкачественными» формами неопределенного поведения (такими как целочисленное переполнение в вычислении, которое в конечном итоге игнорируется), может вызвать произвольное выполнение программы.
источник
int arr[5][[5]
, попытка доступаarr[0][5]
приведет к неопределенному поведению. Такое правило делает возможным для компилятора, которому дано что-то вродеarr[1][0]=3; arr[0][i]=6; arr[1][0]++;
вывода, котороеarr[1][0]
будет равно 4, без учета значенияi
.Исторические причины. Я не часто пишу новый код, в основном я поддерживаю и расширяю старые вещи, которые работают уже десятилетия. Я просто счастлив, что это С, а не Фортран.
Я могу раздражаться, когда какой-то студент говорит: «Но с какой стати ты делаешь этот ужасный Х, когда ты можешь делать Y?». Ну, Х - это моя работа, и она очень хорошо оплачивает счета. Иногда я делал Y, и это было весело, но большинство из нас делают X.
источник
Что такое "опасно"?
Утверждение, что C «опасен», является частым предметом разговора в языковых войнах пламени (чаще всего по сравнению с Java). Тем не менее, доказательства этого требования неясны.
C - это язык с определенным набором функций. Некоторые из этих функций могут допускать определенные типы ошибок, которые не допускаются другими типами языков (обычно выделяется риск управления памятью в C). Однако это не то же самое, что аргумент, что C более опасен, чем другие языки в целом . Я не знаю никого, кто бы предоставил убедительные доказательства по этому вопросу.
Кроме того, «опасный» зависит от контекста: что вы пытаетесь сделать, и какие риски вы беспокоитесь?
Во многих контекстах я бы посчитал C более «опасным», чем язык высокого уровня, потому что он требует от вас больше ручной реализации основных функций, увеличивая риск ошибок. Например, выполнять некоторую базовую обработку текста или разработку веб-сайта на C обычно глупо, потому что другие языки имеют функции, которые делают это намного проще.
Тем не менее, C и C ++ широко используются для критически важных систем, поскольку меньший язык с более прямым контролем над hardward считается «более безопасным» в этом контексте. Из очень хорошего ответа переполнения стека :
источник
Чтобы добавить к существующим ответам, все хорошо, что вы выберете Python или PHP для своего проекта из-за их относительной безопасности. Но кто-то должен реализовать эти языки, и когда они это сделают, они, вероятно, собираются сделать это на C. (Или, ну, что-то вроде этого).
Вот почему люди используют C - для создания менее опасных инструментов, которые вы хотите использовать.
источник
Позвольте мне перефразировать ваш вопрос:
Опасно использовать любой интересный инструмент, в том числе языки программирования. Вы узнаете больше, чтобы сделать больше (и чтобы при использовании инструмента создавалась меньшая опасность). В частности, вы изучаете инструмент так, чтобы вы могли делать то, для чего этот инструмент хорош (и, возможно, узнавать, когда этот инструмент является лучшим инструментом из известных вам инструментов).
Например, если вам нужно вставить цилиндрическое отверстие диаметром 6 мм и глубиной 5 см в блок из дерева, сверло будет гораздо лучшим инструментом, чем анализатор LALR. Если вы знаете, каковы эти два инструмента, вы знаете, какой инструмент является правильным. Если вы уже знаете, как использовать дрель, вуаля!
С это просто еще один инструмент. Это лучше для некоторых задач, чем для других. Другие ответы здесь обращаются к этому. Если вы выучите некоторую C, вы поймете, когда это правильный инструмент, а когда нет.
источник
Нет особой причины не изучать C, но я бы предложил C ++. Он предлагает большую часть того, что делает C (поскольку C ++ - это супер-набор C), с большим количеством «дополнений». Изучение C до C ++ не является необходимым - они фактически являются отдельными языками.
Другими словами, если бы C был набором деревообрабатывающих инструментов, он, вероятно, был бы:
Вы можете создать что - нибудь с этими инструментами - но ничего хорошего потенциально требует много времени и мастерства.
C ++ - это набор мощных инструментов в вашем местном хозяйственном магазине.
Если вы придерживаетесь базовых языковых возможностей, C ++ имеет относительно небольшую дополнительную кривую обучения.
Потому что некоторые люди не хотят мебель от ИКЕА. знак равно
Если серьезно, то, хотя многие языки, которые «выше» C или C ++, могут иметь вещи, которые делают их (потенциально) «более простыми» в использовании в определенных аспектах, это не всегда хорошо. Если вам не нравится то, как что-то делается, или функция не предоставляется, скорее всего, вы ничего не можете с этим поделать. С другой стороны, C и C ++ предоставляют достаточно «низкоуровневых» языковых возможностей (включая указатели), чтобы вы могли получить доступ ко многим вещам довольно напрямую (особенно с аппаратной или операционной системой) или создать их самостоятельно, что может быть невозможно в других случаях. языки как реализовано.
В частности, C имеет следующий набор функций, которые делают его желательным для многих программистов:
Совместимость - C существует уже давно, и у каждого есть инструменты и библиотеки для него. Сам язык также не требователен - он ожидает, что процессор будет выполнять инструкции, а память - для хранения информации, и это все.
Кроме того, существует нечто, известное как двоичный интерфейс приложения (ABI) . Короче говоря, это способ взаимодействия программ на уровне машинного кода, который может иметь преимущества перед интерфейсом прикладного программирования (API) . В то время как другие языки, такие как C ++, могут иметь ABI, обычно они менее единообразны (согласованы), чем C, поэтому C делает хороший базовый язык, когда вы хотите по какой-то причине использовать ABI для взаимодействия с другой программой.
Эффективность (и иногда схемы управления памятью, которые не могут быть реализованы без относительно прямого доступа к памяти).
Прямой доступ к памяти с помощью указателей вводит много аккуратных (обычно быстрых) трюков, когда вы можете положить свои грязные лапы на маленькие и нули прямо в свои ячейки памяти и не нужно ждать, пока этот учитель раздаст игрушки во время игры, затем выкопайте их снова.
Короче говоря, добавление материала потенциально создает задержку или иным образом создает нежелательную сложность.
Что касается скриптовых языков и тому подобного, вы должны усердно работать, чтобы получить языки, требующие, чтобы вторичные программы работали так же эффективно, как изначально C (или любой скомпилированный язык). Добавление интерпретатора «на лету» по своей сути вводит возможность снижения скорости выполнения и увеличения использования памяти, поскольку вы добавляете в микшер еще одну программу. Эффективность ваших программ зависит как от эффективности этой вторичной программы, так и от того, насколько хорошо (плохо =) вы написали исходный программный код. Не говоря уже о том, что ваша программа часто полностью зависит от второй программы. Эта вторая программа по какой-то причине не существует в конкретной системе? Код не идет.
Фактически, введение чего-то «лишнего» потенциально замедляет или усложняет ваш код. В языках «без страшных указателей» вы всегда ждете, чтобы другие кусочки кода очистились позади вас, или иным образом выясните «безопасные» способы сделать что-то - потому что ваша программа все еще выполняет те же операции доступа к памяти, что и с указатели. Вы просто не тот, кто с этим справляется (так что вы не можете его обдумать, genius = P).
Согласно принятому ответу:
Представление о том, что, поскольку что-то может быть сделано на языке, это должно быть сделано, глупо. У языков есть недостатки, которые исправляются. По соображениям совместимости со старым кодом эта конструкция все еще может использоваться. Но нет ничего (вероятно), заставляющего программиста использовать get (), и, фактически, эта команда была по существу заменена более безопасными альтернативами.
Более того, проблема с get () сама по себе не является проблемой указателя . Это проблема с командой, которая не обязательно знает, как безопасно использовать память. В абстрактном смысле, это все проблемы с указателями - чтение и запись вещей, которые вы не должны делать. Это не проблема с указателями; это проблема с реализацией указателя.
Чтобы уточнить, указатели не опасны, пока вы случайно не получите доступ к области памяти, которую вы не собирались. И даже тогда это не гарантирует, что ваш компьютер тает или взрывается. В большинстве случаев ваша программа просто перестанет функционировать (правильно).
Тем не менее, поскольку указатели предоставляют доступ к областям памяти и поскольку данные и исполняемый код существуют в памяти вместе, существует реальная опасность случайного повреждения, что вы хотите правильно управлять памятью.
В связи с этим, поскольку в действительности операции прямого прямого доступа к памяти часто дают меньше преимуществ, чем они могли бы получить много лет назад, даже языки без сбора мусора, такие как C ++, ввели такие вещи, как интеллектуальные указатели, чтобы помочь преодолеть разрыв между эффективностью и безопасностью памяти.
Таким образом, существует очень мало причин бояться указателя, если он используется безопасно. Просто возьмите намек на версию Стива "Охотник за крокодилами" Ирвина из Саут-Парка - не торопитесь засунуть большой палец в дырки крокодилов .
источник
Как всегда, язык программирования является лишь следствием решения проблем. На самом деле вы должны выучить не только C, но и много разных языков (и других способов программирования компьютера, будь то GUI-инструменты или интерпретаторы команд), чтобы иметь приличный инструментарий для решения проблем.
Иногда вы обнаружите, что проблема хорошо подходит для чего-то, что включено в библиотеки Java по умолчанию, в таком случае вы можете выбрать Java, чтобы использовать это. В других случаях может случиться так, что вам нужно сделать что-то в Windows, что намного проще во время выполнения .NET, поэтому вы можете использовать C # или VB. Там может быть графический инструмент или командный скрипт, который решит вашу проблему, тогда вы можете использовать их. Возможно, вам нужно написать приложение с графическим интерфейсом на нескольких платформах, Java может быть вариантом, учитывая включенные библиотеки в JDK, но с другой стороны, на одной целевой платформе может отсутствовать JRE, поэтому, возможно, вы вместо этого выберете C и SDL (или аналог).
C занимает важное место в этом наборе инструментов, так как он общий, небольшой и быстрый, а также компилируется в машинный код. Он также поддерживается на каждой платформе под солнцем (однако не без перекомпиляции).
В итоге вы должны выучить как можно больше инструментов, языков и парадигм.
Пожалуйста, отойдите от мышления: «Я программист X» (X = C, C ++, Java и т. Д.)
Просто используйте «Я программист».
Программист решает проблемы и разрабатывает алгоритмы, инструктируя машины выполнять рабочую нагрузку. Конец истории. Это не имеет отношения к языку. Ваш самый важный навык - это решение проблем и логическая разбивка структурированных проблем, языковой навык / выбор ВСЕГДА вторичен и / или является следствием характера проблемы.
Интересный путь, если вы заинтересованы в C, - это расширить свой набор навыков с помощью Go. Go - действительно улучшенный C, со сборщиком мусора и интерфейсами, а также с хорошей встроенной потоковой моделью / каналами, которые также приносят многие преимущества C (такие как арифметика указателей и компиляция в машинный код).
источник
Это зависит от того, что вы собираетесь с этим делать. C был разработан для замены языка ассемблера и является языком высокого уровня, наиболее близким к машинному языку. Таким образом, он имеет низкие накладные расходы по размеру и производительности и подходит для системного программирования и других задач, которые требуют небольшой площади и приближаются к базовому оборудованию.
источник
Когда вы работаете на уровне битов и байтов памяти, как сырой однородный сбор данных, что часто требуется для эффективной реализации наиболее эффективных распределителей и структур данных, безопасность не требуется. Безопасность - это преимущественно концепция, связанная с типами данных, а распределитель памяти не работает с типами данных. Он работает с битами и байтами для объединения с теми же битами и байтами, потенциально представляющими один тип данных один момент, а другой позже.
Не имеет значения, используете ли вы C ++ в этом случае. Вы по-прежнему будете разбрасывать
static_casts
весь код для приведения изvoid*
указателей и все еще работать с битами и байтами и просто иметь дело с большим количеством хлопот, связанных с уважением системы типов в этом контексте, чем в C, который имеет гораздо более простую систему типов, где вы свободны наmemcpy
кусочки и байты вокруг, не беспокоясь о бульдозере над системой типов.На самом деле, в таких низкоуровневых контекстах битов и байтов часто труднее работать в C ++, в целом более безопасном языке, без написания даже более опасного кода, чем в C, поскольку вы могли бы разбираться с системой типов C ++ и делать такие вещи, как перезаписывать vptrs и не вызывать конструкторы и деструкторы копирования в подходящее время. Если вы уделите должное время уважению этих типов и используете размещение новых и вызовете dtors вручную и т. Д., То вы попадаете в мир обработки исключений в контексте слишком низкого уровня, чтобы RAII был практичным, и достигали исключения. безопасность в таком низкоуровневом контексте очень трудна (вы должны притворяться, будто любая функция может выбросить и поймать все возможности и откатить любые побочные эффекты как неделимую транзакцию, как будто ничего не произошло). Код C часто может
И было бы невозможно реализовать такие распределители на языках, которые не позволяют вам становиться «опасными» здесь; вам придется опираться на любые предоставляемые ими распределители (реализованные, скорее всего, на 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 десятилетия спустя, потому что вы не можете вводить новшества на уровне, необходимом для достижения с двигателем следующего поколения, просто делая высокоуровневые звонки на старый.
источник