Каковы были бы ограничения C ++ по сравнению с языком C? [закрыто]

116

Ниже приведены преимущества C ++.

  • C ++ предоставляет конкретные функции, о которых они спрашивают
  • Их компилятор C почти наверняка действительно является компилятором C ++, поэтому нет никаких финансовых последствий для программного обеспечения.
  • C ++ такой же переносимый, как и C
  • Код C ++ может быть таким же эффективным, как C (или более, или менее)

Есть ли какие-то конкретные причины и конкретные сценарии, когда нужно использовать C вместо C ++?

Ссылка на этот вопрос: Библиотека дженериков на C

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

Сообщение Питера Киркхэма было для меня наиболее информативным, особенно в отношении вопросов C99, которые я не рассматривал, поэтому я его принял. Спасибо всем, кто принимал участие.

анон.
источник
12
Неважно, задуман ли этот вопрос как аргумент или нет, он все же так и есть. Выбор языка для проекта - это именно выбор.
Bombe
7
@bombe, разве мы не должны обсуждать, как делать осознанный выбор?
4
DUPLICATE ... см .: 1. stackoverflow.com/questions/145096/… 2. stackoverflow.com/questions/482574/…
Trevor Boyd Smith
10
Разве не забавно, когда вы даете совет программистам на C перейти на C ++, что они примерно так же восприимчивы к вашей идее, как и вы, если бы программист на C сказал вам, что вы должны отказаться от C ++ и перейти на C?
Warren P

Ответы:

136

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

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

Это действительно C:

foo_t* foo = malloc ( sizeof(foo_t) );

Чтобы он компилировался как C ++, вам нужно написать:

foo_t* foo = static_cast<foo_t*>( malloc ( sizeof(foo_t) ) );

который больше не действителен C. (вы можете использовать приведение в стиле C, в этом случае он будет компилироваться на C, но его избегают большинство стандартов кодирования C ++, а также многие программисты на C; обратите внимание на комментарии «не приводить malloc» во всем стеке) ,


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

Принимая первый файл C в проекте я работаю, это то , что произойдет , если вы просто своп gcc std=c99для g++:

sandiego:$ g++ -g  -O1 -pedantic -mfpmath=sse -DUSE_SSE2 -DUSE_XMM3  -I src/core -L /usr/lib -DARCH=elf64 -D_BSD_SOURCE -DPOSIX -D_ISOC99_SOURCE -D_POSIX_C_SOURCE=200112L -Wall -Wextra -Wwrite-strings -Wredundant-decls -Werror -Isrc  src/core/kin_object.c -c -o obj/kin_object.o | wc -l
In file included from src/core/kin_object.c:22:
src/core/kin_object.h:791:28: error: anonymous variadic macros were introduced in C99
In file included from src/core/kin_object.c:26:
src/core/kin_log.h:42:42: error: anonymous variadic macros were introduced in C99
src/core/kin_log.h:94:29: error: anonymous variadic macros were introduced in C99
...
cc1plus: warnings being treated as errors
src/core/kin_object.c:101: error: ISO C++ does not support the z printf length modifier
..
src/core/kin_object.c:160: error: invalid conversion from void*’ to kin_object_t*’
..
src/core/kin_object.c:227: error: unused parameter restrict
..
src/core/kin_object.c:271: error: ISO C++ does not support the z printf length modifier
src/core/kin_object.c:271: error: ISO C++ does not support the z printf length modifier

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

Не то чтобы я использовал эти функции для развлечения. Перенос его на другой язык потребует значительных усилий.

Поэтому совершенно неправильно предполагать, что

[a] Компилятор C почти наверняка на самом деле является компилятором C ++, поэтому нет никаких финансовых последствий для программного обеспечения.

Портирование существующего кода C на процедурное подмножество C ++ часто сопряжено со значительными затратами.

Поэтому предлагать «использовать класс C ++ std :: queue» в качестве ответа на вопрос, ищущий библиотечную реализацию очереди на C, является более низким, чем предлагать «использовать объект и «вызвать класс Java java.util.Queue с помощью JNI». или «вызвать библиотеку CPython» - Objective C на самом деле является правильным надмножеством C (включая C99), а библиотеки Java и CPython можно вызывать непосредственно из C без необходимости переносить несвязанный код на язык C ++.

Конечно, вы можете добавить фасад C к библиотеке C ++, но как только вы это сделаете, C ++ ничем не отличается от Java или Python.

Пит Киркхэм
источник
21
Да. Приведение в стиле C - обычное дело при использовании malloc. Когда вы используете malloc, вы остаетесь в подмножестве c. Если вы хотите запрограммировать стиль C ++, вы должны использовать оператор new, а не static_cast + malloc.
Suma
33
Сказать, что C не является подмножеством C ++, невероятно педантично. Конечно, вы могли бы сказать, что любая структура с членом, называемым «класс», не будет компилироваться, но на самом деле требуются лишь незначительные изменения, и у большинства компиляторов есть опции для добавления нескольких функций только для C в C ++.
Kaz Dragon
27
Что касается вашего примера с malloc, добавление приведения будет избегать не только программисты на C ++, но и (особенно) программисты на C. Есть веские причины не использовать приведение в коде C. В этом нет необходимости, и добавление может скрыть ошибки. Так что относитесь к ним как к двум отдельным языкам. +1 :)
jalf
26
@BlueRaja Представьте себе, если бы Гвидо решил не добавлять объекты к своему языку сценариев, и две группы создали взаимно несовместимые вилки Python для добавления объектов, одна с объектной моделью на основе Smalltalk, а другая с системой классов на основе Simula. Затем Гвидо продолжил улучшать Python, сосредоточив внимание на его основном использовании. Это ближе к ситуации C / Objective C / C ++.
Пит Киркхэм
11
@BlueRaja: это два разных языка, которые имеют довольно большое общее ядро. Если вы программируете на этом общем ядре, вы закончите делать вещи, которые не являются хорошим кодом на любом из языков. Выберите один язык для написания любой данной программы и сделайте ее хорошей на этом языке.
Дэвид Торнли,
115

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

Если мне удастся выбрать, я напишу все высокоуровневые вещи, такие как интерфейс и взаимодействие с базой данных на python (или, возможно, C #), и все вещи, которые должны быть быстрыми на C. Для меня это дает мне лучшее из всех миров. Написание всего на C ++ похоже на худшее из миров.

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

dagw
источник
24
Я использовал C ++ в течение нескольких лет и все еще тратил 50% времени на рефакторинг кода, чтобы он был «правильным для C ++». Как вы говорите, это кошмар.
Кай
12
Вы всегда можете сделать это правильно с первого раза. Добавить const нетрудно.
GManNickG
14
Я использовал C ++ в течение десяти лет, и возвращение к C (для встраиваемых систем в моем случае) было лучшим, что я когда-либо делал.
Warren P
Мне нравится этот ответ. Ты тоже приколол мои чувства. У меня были годы работы в качестве разработчика C ++, моя повседневная работа по- прежнему C ++. Но это не значит, что мне нравится язык, я вижу красоту в C.
Мэтт Джойнер
10
+1, В связи с этим я считаю , что каждый раз , когда я пишу C ++ Я в конечном итоге тратят гораздо больше времени для отладки и стучать головой о твердую поверхность , чем когда я кода C . Не могу с тобой больше согласиться. Лучший ответ. :)
ApprenticeHacker
58

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

Йоонас Пулакка
источник
2
Правильно. Я видел компиляторы c для 8-битных микроконтроллеров.
dmckee --- котенок экс-модератора
6
конечно. В наши дни большинство, если не все 8-битные чипы имеют компиляторы C.
Эли Бендерский
gbdk.sourceforge.net - GBDK для одного ..
Келден Коуэн,
+1 это правильный ответ. Компиляторы C ++ писать намного сложнее, чем компиляторы C, в основном из-за сложности (множественного) наследования.
BlueRaja - Дэнни Пфлугофт
9
@BlueRaja: по сравнению с шаблонами ... множественное наследование здесь не может быть настоящим сдерживающим фактором. В конце концов, шаблоны представляют собой полноценный собственный язык.
Matthieu M.
49

Ненавижу программирование на C ++.

Георг Шёлли
источник
6
Lol, мне нравится этот
Tamas Czinege
30
Очень убедительно! Я подумываю перейти на Python, основываясь на ваших аргументах.
Джимми Дж,
8
Может быть, не убедительно, но это истинная причина.
Георг Шёлли,
@ Джимми Дж .: Python невероятен. Это лучшее из Unix, C и всех ваших "современных" языковых функций, сделанных правильно. Если у вас есть проблемы с производительностью, Python хочет , чтобы вы перешли на C, и это делает легко.
Мэтт Джойнер
2
@Georg: Признаюсь, я никогда не смотрел, я так впечатлен Python.
Мэтт Джойнер
38

Может быть несколько причин:

  • Отсутствие поддержки - не каждый компилятор C также является компилятором C ++. Не все компиляторы особенно соответствуют стандарту, даже если они утверждают, что поддерживают C ++. А некоторые компиляторы C ++ генерируют безнадежно раздутый и неэффективный код. Некоторые компиляторы имеют ужасные реализации стандартной библиотеки. Разработка в режиме ядра обычно делает невозможным использование стандартной библиотеки C ++, а также некоторых языковых функций. Вы по-прежнему можете писать код на C ++, если будете придерживаться ядра языка, но тогда будет проще переключиться на C.
  • Дружественные. C ++ - сложный язык. Легче научить кого-то C, чем C ++, и легче найти хорошего программиста на C, чем хорошего программиста на C ++. (ключевое слово здесь "хорошо". Программистов на C ++ много, но большинство из них не выучили язык должным образом)
  • Кривая обучения - Как и выше, обучить кого-то C ++ - огромная задача. Если вы пишете приложение, которое должны поддерживать другие в будущем, и эти другие могут не быть программистами на C ++, написание его на C значительно упрощает освоение.

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

jalf
источник
4
Я бы добавил, что код C компилируется намного быстрее, чем C ++. Большой проект в нашей компании (более миллиона строк) компилируется меньше 30 секунд.
Calmarius
31

Есть масса аргументов о встроенном программировании, производительности и прочем, я на них не верю. C ++ легко сравнивается с C в этих областях. Тем не мение:

Совсем недавно, после 15 лет программирования на C ++, я заново открыл для себя свои корни C. Я должен сказать, что, хотя в C ++ есть хорошие функции, облегчающие жизнь, есть также множество подводных камней и своего рода «всегда есть лучший способ». На самом деле вы никогда не будете довольны принятым решением. (Не поймите меня неправильно, это могло бы быть хорошо, но в основном нет).

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

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

Андерс Ханссон
источник
8
Без обид, но это также может зависеть от того, что вы думаете о C ++. Наследование - это то, что я больше ассоциирую с Java, чем с C ++, и если вы относитесь к C ++ строго как к объектно-ориентированному языку, а именно Java (C с классами), то я согласен с вами. Если вы придерживаетесь более современного варианта C ++, я думаю, что это веселее, чем C
jalf
11
Еще раз повторю, что я не считаю C ++ языком объектно-ориентированного программирования, и его не следует рассматривать как таковой. Я думаю, что универсальное программирование - гораздо более сильная черта C ++. Большая часть кода C ++, который я вижу, не особо старается быть «объектно ориентированным» или содержать ненужный код. Часто он более компактный, чем эквивалентный код C
jalf
3
@jalf: Еще одна вещь, которая, как я считаю, может отвлекать в C ++ от «всегда есть лучший способ», - это обобщение вещей с помощью шаблонов. «Может быть, мы должны позволить пользователю этого класса решать, какой базовый целочисленный тип использовать?» Но вам, вероятно, это не нужно , и в C вы бы не стали беспокоиться. И иногда я ловлю себя на мысли: «Нам действительно следует предоставить интерфейс прямого итератора для этого класса», тогда как в C вы просто выставляете указатель на первый элемент и счетчик или (верх фантазии!) Функцию, принимающую указатель на функцию обратного вызова.
j_random_hacker 06
2
Я делаю шаг назад, когда кодирование на C ++ помогает. Определите цель и напишите о ней (стиль C). Фактор "измов" C ++ по мере того, как их полезность становится очевидной.
Мэтт Джойнер
2
infinite gunfire, о да, так верно. Наши ноги буквально дрожат :)
quetzalcoatl
27

У C есть главное преимущество в том, что вы можете просто увидеть, что происходит на самом деле, когда вы смотрите на какой-то фрагмент кода (да, препроцессор: скомпилируйте с -E, а затем вы это увидите). То, что слишком часто не соответствует действительности, если вы посмотрите на код C ++. Там у вас есть конструкторы и деструкторы, которые вызываются неявно на основе области видимости или из-за присваиваний, у вас есть перегрузка оператора, которая может иметь удивительное поведение, даже если оно не используется неправильно. Признаюсь, я помешан на контроле, но пришел к выводу, что это не такая уж плохая привычка для разработчика программного обеспечения, который хочет писать надежное программное обеспечение. Я просто хочу иметь шанс сказать, что мое программное обеспечение делает именно то, что должно делать, и в то же время не вызывает неприятных ощущений в животе, потому что я знаю, что в нем все еще может быть так много ошибок, что я бы не стал ''

В C ++ также есть шаблоны. Я ненавижу и люблю их, но если кто-то говорит, что полностью понимает их, я называю его / ее лжецом! Это включает в себя составителей компилятора, а также людей, участвующих в определении стандарта (что становится очевидным, когда вы пытаетесь его прочитать). Существует так много абсурдно вводящих в заблуждение угловых случаев, что просто невозможно рассмотреть их все, пока вы пишете реальный код. Мне нравятся шаблоны C ++ за их мощь. Действительно удивительно, что вы можете с ними сделать, но они также могут привести к самым странным и трудным для поиска ошибкам, которые только можно (не) вообразить. И эти ошибки действительно случаются и даже не редко. Чтение о правилах, используемых для разрешения шаблонов в C ++ ARM, чуть не взорвало мою голову. И это вызывает у меня неприятное чувство потраченного впустую времени на чтение сообщений об ошибках компилятора длиной в несколько 1000 символов, для которых мне нужно уже 10 минут или больше, чтобы понять, что компилятор действительно хочет от меня. В типичном коде C ++ (библиотеки) вы также часто находите много кода в файлах заголовков, чтобы сделать определенные шаблоны возможными, что, в свою очередь, делает циклы компиляции / выполнения мучительно медленными даже на быстрых машинах и требует перекомпиляции больших частей кода, когда вы что-то меняете. там.

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

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

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

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

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

Жизнь коротка...

x4u
источник
2
+1, не могу не согласиться.
missingfaktor
2
Это звучит удивительно аналогично аргументу Линуса. (Меньше контекста объекта = легче понять.)
Уоррен П.
20

В низкоуровневой встраиваемой среде некоторые из «инженеров-программистов» будут иметь опыт работы с EE и едва освоить C. C ++ более сложен, и некоторые из этих ребят просто боятся изучать новый язык. Таким образом, C используется как наименьший общий знаменатель. (Прежде чем вы предложите избавиться от этих парней, они по крайней мере так же важны, как и специалисты по CS, которые не понимают хардкорных аналоговых вещей.)

Исходя из опыта унаследованных и поддерживаемых обоих: ужасный дизайн на C трудно понять, развеять и преобразовать во что-то полезное.

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

Если мне придется работать с инженерами, которые, как я знаю, не будут создавать отличных проектов, я бы предпочел первое, чем второе.

bstpierre
источник
Аминь, брат. После работы с исходным кодом C, созданным инженерами по аппаратному обеспечению, я с содроганием думаю о том, с чем я столкнулся бы, если бы они сделали это на C ++.
Ричард Чемберс
19

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

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

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

Suma
источник
3
Класс с виртуальными функциями имеет больше накладных расходов: каждый экземпляр должен иметь дополнительное поле для идентификации типа.
bstpierre
6
Больше накладных расходов, чем какие? Тип переносится в vtbl. Если вы реализуете аналогичный механизм с использованием указателей функций, вам понадобится хотя бы один указатель (или индекс, или что-то еще), чтобы выбрать указатель функции, который вы хотите использовать.
Suma
3
bstpierre: Я думаю, что Suma говорит о том, что у нее не больше накладных расходов, чем вручную реализовать эту функцию на C.
Мартин Йорк
2
Указатель на классы vtable хранится в каждом экземпляре класса.
tstenner
5
Есть накладные расходы, но я имею в виду, что если вы хотите какое-либо разрешение динамического типа, вам понадобится некоторое хранилище для идентификации типа, даже в C.Если вам не нужны динамические типы, вам не нужно оплачивать накладные расходы ( не используйте виртуальные функции, если они вам не нужны).
Suma
13

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

Это тот же аргумент, но с очевидными заблуждениями. Если у вас есть задача, и ваши удобные инструменты решают ее эффективно, вы, вероятно, воспользуетесь удобными инструментами не зря.

SPWorley
источник
3
Если бы я говорил и на английском, и на сербском, я уверен, что был бы более изобретательным. Вы не согласны?
2
@Neil действительно, но усилия, необходимые для изучения сербского, могут быть неоправданными для решения моего текущего творческого блока.
slim
2
Я думаю, что Арно подчеркивает тот факт, что вы пишете не для процессора, вы пишете для своих коллег, чтобы их читали, а другие библиотеки - для компоновки, и так далее. В конце концов, если бы я просто стремился к выразительности и скорости, я бы написал на OCaml.
Кен
10

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

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

quinmars
источник
1
Эм ... нет? Вы изучаете основу C (возможно, за исключением массивов и обработки строк в стиле C, отказавшейся в пользу <vector> и <string>), и приступайте. Вы можете подобрать все остальное по ходу дела. Вам не нужно ничего знать об OO, GP или исключениях, чтобы начать работу с C ++ ...
DevSolar,
4
C может быть «меньше», но в долгосрочной перспективе его не легче использовать. Ручное управление памятью? Нет, спасибо.
Джимми Дж,
7
В C ++ нет такой вещи, как автоматическое управление памятью.
Warren P
3
C ++ не решает проблему управления памятью. Когда вы подумали, что умеете обращаться с указателями, C ++ добавляет ужасную модель исключений. Приходите на землю C99. За исключением структур данных, я почти уверен, что почти не касаюсь malloc. Даже тогда я могу «инкапсулировать» несколько вызовов malloc. Во многом та же история в C ++ (неявное управление памятью, только это делается в куче, а не в стеке), только со всем джазом умных указателей.
Мэтт Джойнер
1
@ereOn: Это правда, комментарий, который я написал 3 года назад, больше не актуален. :)
Мэтт Джойнер
10

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

  1. Строгое соблюдение стандартов кодирования может быть трудным
  2. Придумать хороший вариант бывает очень сложно.

Я думаю, что вторая причина здесь гораздо более важна, чем первая, потому что выбор стандарта кодирования может легко стать политическим вопросом и впоследствии может быть пересмотрен. Рассмотрим следующий упрощенный случай:

  1. Вам разрешено использовать контейнеры stl, но не использовать шаблоны в каком-либо собственном коде.
  2. Люди начинают жаловаться, что они были бы более продуктивными, если бы им просто разрешили кодировать тот или иной шаблонный класс.
  3. Для этого пересмотрен стандарт кодирования.
  4. Перейдите к чрезмерно сложному стандарту кодирования, которому никто не следует, и используйте именно тот опасный код, который стандарт должен был предотвратить, в сочетании с излишней бюрократией, окружающей стандарт.

(Альтернатива, когда стандарт не пересматривается на шаге 3, эмпирически слишком маловероятна для рассмотрения и в любом случае не будет намного лучше.)

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

TrayMan
источник
10

Я использую C или, по крайней мере, экспортирую интерфейс C, когда пишу код библиотеки.

Я не хочу, чтобы сбои с ABI были неопределенными.

Ритмичный кулак
источник
Тем же. Строгий C только в интерфейсах. Меньше всего я хочу, чтобы мне навязывали чью-то нелепую объектную структуру.
Мэтт Джойнер
9

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

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

Дэн Олсон
источник
3
Согласны, тирады «C лучше, чем C ++» никогда не выдерживают критики.
Джимми Дж,
6
Я считаю, что C ++ предлагает мне ОЧЕНЬ НЕБОЛЬШУЮ выгоду и СТОИТ МНЕ огромного количества случайных сложностей. Я считаю, что потребуется около 1500 страниц учебников по C ++ и десять лет усилий, чтобы стать таким же профессиональным в C ++, как я сейчас в C, Pascal, Python и Objective-C. Каждый из вышеперечисленных языков примерно в 20 раз более ортогонален, компактен и психологически удобен в использовании, не говоря уже о более мощных в тех средах, где я их использую. В моих обычных средах разработки для C ++ просто НЕТ рационально оправданного использования.
Warren P
@Warren Вы платите только за то, что используете, как и за любой язык. Если вы не можете решить, как правильно писать код на C ++, то это на вас, а не на языке.
Дэн Олсон
2
Не так. Если вы единственный разработчик в проекте, это может быть так. Но как только у нас есть два разработчика, у нас есть баталии. Какой? Вы настаиваете на контейнерах IoC, тогда как я предпочитаю другой способ делегирования ... Вам нравятся три уровня вложенных шаблонов, а я предпочитаю нулевые шаблоны. Бардак.
Warren P
Я знаю, что этому посту 10 лет, но разве справедливо даже сравнивать C и C ++? Оба являются отдельными, расходящимися языками (начиная с C99), и у каждого из них есть свои преимущества и недостатки. C ++ сложно отлаживать и поддерживать? Явность C позволяет вам лучше отлаживать. C не имеет дженериков? В C ++ есть дженерики! На данный момент ни один язык не может быть лучше другого.
Nergal
9

Один вопрос, который я еще не поднимал, я считаю самым важным:

Большинство библиотек, которые я использую ежедневно, - это библиотеки C с привязками для Python, Ruby, Perl, Java и т. Д. Из того, что я видел, намного проще обернуть библиотеки C 19 различными языковыми привязками, чем для обернуть библиотеки C ++.

Например, я выучил Каир однажды и с тех пор использовал его на 3 или 4 разных языках. Большая победа! Я бы предпочел написать программу, которую можно было бы снова использовать в будущем, и написание программы, которую можно было бы легко адаптировать к другим языкам программирования, является крайним случаем.

Я знаю, что можно связывать библиотеки C ++, но, AFAICT, это не то же самое. Я использовал Qt (v3 и v4) на других языках, и это далеко не так приятно использовать: им кажется, что писать C ++ на каком-то другом языке, а не на нативных библиотеках. (Вы должны передавать сигнатуры методов C ++ в виде строк!)

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

кругозор
источник
«Передавать методы как строки!» вещь дефект Qt, а не C ++. На самом деле у вас может быть такой же дурацкий механизм с фреймворком C. Даже ребята из Qt согласны с тем, что это было ошибкой. В то время в их сознании просто не было лучшей альтернативы, и было уже слишком поздно менять ее, когда они поняли.
ereOn 06
7

Разработка ядра Windows не поддерживает C ++ (к сожалению).

LegendLength
источник
Как так? Зачем? Отличается ли двоичный файл, созданный компилятором C ++, от компилятора C? Разве разработка драйверов не соответствует API?
Дэйв Ван ден Эйнде,
4
Потому что многие функции C ++ требуют поддержки во время выполнения, что может быть нетривиальной задачей для реализации в режиме ядра. Во-первых, используются разные функции выделения памяти, поэтому необходимо заменить фрагменты стандартной библиотеки. Исключения - это тоже плохо.
jalf
3
Я добавлю, что Linux Torvalds, к счастью, свел на нет все шансы появления C ++ в Linux по не только причинам. Было несколько ОС на других языках: Java, C ++, ассемблер. Уцелели только ассемблерные при разумном использовании.
Мэтт Джойнер
Заметили это для Visual Studio 2015?
LegendLength 05
6

Вы можете прочитать занимательную тираду о том, почему Линус Торвальдс предпочитает C здесь

Пол Диксон
источник
6
Это скорее полусогласованная тирада против объектно-ориентированного дизайна, чем тирада против C ++.
Дэн Олсон,
16
У г-на Торвальдса есть длинный список вещей, которые ему не нравятся: C ++, emacs, Subversion, объектно-ориентированный подход и многие другие. Иногда хочется, чтобы он еще немного
11
Линус любит разглагольствовать и пытаться спровоцировать и расстроить людей. К сожалению, он не потрудился изучить C ++, прежде чем заявил, что это отстой. К сожалению, его последователи считают, что все, что он говорит, должно быть правдой.
jalf
9
Ссылка была больше для развлечения, чем для образования
Пол Диксон
6
Доказательство того, что даже гении иногда бывают болваном.
Kaz Dragon
5

Собственный код на Mac является объективным-c. Собственный код на ПК - это c (window.h) или c ++ (mfc). Обе эти среды позволят вам использовать c с небольшими изменениями или без них. Когда я хочу, чтобы библиотека кода была кроссплатформенной, мне кажется, что это хороший выбор.

Ник Ван Брант
источник
4

Я могу придумать несколько причин.

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

Спрашивающий или люди, с которыми он работает, могут быть знакомы с C, но не с C ++.

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

У спрашивающего может быть устаревшее представление о кривой обучения C ++. (При правильном подходе это легче, чем C. Большинство вводных книг, которые я видел, не подходят к этому правильно.)

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

Дэвид Торнли
источник
3

Если вы работаете в среде с двумя языками, вы можете использовать C для некоторых критически важных для производительности низкоуровневых функций и более функциональный / высокоуровневый язык, такой как C # / Java, для бизнес-логики. Если для этих функций используется код C ++, для JNI / неуправляемого кода требуются C-Wrappers, и это усложняет задачу, чем использование только C.

weismat
источник
3

Я использую C ++ с программированием на C по двум причинам:

  • vectorи stringизбавиться от управления памятью массива
  • строгая проверка типов и приведение типов, чтобы предупредить и / или уловить все неприятности, которые в противном случае я бы пропустил.

Так что C действительно заимствует немного C ++, но использует компилятор C ++ по мере возможности. Как говорит кто-то другой в ответах, я обнаружил, что теперь я на самом деле набираю больше C ++ таким образом, и там, где C будет слишком вовлечен, я использую C ++. Монитор / блокировка с использованием RAII - одна из тех, которые я недавно использовал при работе с многопоточными программами, и другую аналогичную конструкцию для открытия / закрытия файлов.

dubnde
источник
3

Я думаю, что C более портативен. Около 5 лет назад я работал над переносом кода на многие разновидности unix (AIX, Irix, HPUX, Linux). Код C было легко перенести, но у нас были различные проблемы с переносом части кода C ++. Возможно, это была просто незрелая среда разработки, но по этой причине я бы предпочел использовать C вместо C ++ ...

Гордон Томпсон
источник
1
Пятнадцать лет назад я был ведущим разработчиком проекта C ++, ориентированного на HPUX, AIX и Solaris. У нас было очень мало проблем с переносимостью C ++ - почти все из них были связаны с несовместимостью системных вызовов C.
1
Менее десяти лет назад я работал над проектом с использованием HPUX, Solaris и Tru64 с использованием традиционных компиляторов. Наши ночные клубы никогда не строились. Когда мы добавляли AIX, мы решили перейти на стандартный C ++.
Дэвид Торнли,
Может быть, люди, написавшие ваш код, были лучшими кодировщиками, чем та чушь, с которой мне приходилось иметь дело :-)
Гордон Томпсон
3
  1. C - простой язык, C ++ - нет. Для многих людей C ++ слишком сложен для полного освоения, см. Http://en.wikipedia.org/wiki/C%2B%2B#Criticism .

  2. Из-за сложности разные программисты обычно владеют только разными подмножествами языка. Это делает чтение чужого кода болезненным.

  3. Сложность и недостатки языка слишком сильно отвлекают, а иногда снижают продуктивность. Вместо того чтобы сосредоточиться на самой работе, я часто боролся с самим языком. Java / python - более производительные альтернативы.

  4. Отладка поврежденного кода C обычно намного проще, чем отладка неисправного кода C ++.

  5. В отличие от Java / C #, стандартная библиотека C ++ мало что выходит за рамки стандартной библиотеки C.

  6. Некоторые известные программисты, такие как Линус Торвальдс (Linux) и Ричард Столлман (Emacs), не любят C ++.

Алан Брэдли
источник
3
Я подумывал проголосовать за ваш ответ до тех пор, пока не прочитал аргумент №6.
fuz 01
1

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

Роб де Фрисс
источник
1
Хм, причина, по которой я переключился с C на C ++ (давным-давно), заключалась в более строгой проверке типов. Мне нравится, когда мои ошибки обнаруживает компилятор, а не пользовательский дамп памяти.
1

Я могу придумать три причины. Во-первых, C больше подходит для встроенных систем из-за небольшого размера его двоичных файлов и более широкой доступности компиляторов C в любой системе. Вторая - это переносимость: C - это меньший по размеру язык, и код ANSI C компилируется где угодно. На C ++ легче нарушить переносимость. Последнее - это сам язык. C ++ сложнее и определенно является очень плохо разработанным языком. Грипсы Торвальдса описаны выше. Вы также можете посмотреть ответы на часто задаваемые вопросы C ++ ( http://yosefk.com/c++fqa/ ).

с промежутками
источник
5
И, если вы умны, посмотрев FQA, вы поймете, что это хакерская работа того, кто на самом деле не понимает C ++, но все равно ненавидит его.
Дэвид Торнли
1

Может возникнуть проблема с переносимостью. В отличие от ответа Гордона Карпентера-Томпа, я бы предположил, что это скорее поддержка времени выполнения разных версий libstdc ++ в разных версиях linux / unix. См. Эту ссылку для хорошего обсуждения этого. Небольшой отрывок:

Код поддержки среды выполнения, используемый различными частями приложения C ++, должен быть совместимым. Если одной части программы требуется dynamic_cast или перехватить объекты, предоставленные другой, обе части должны согласовать определенные детали реализации: как найти vtables, как раскрутить стек и так далее.

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

ferdystschenko
источник
1

Здесь я могу следовать многим предложениям в обоих направлениях. Но в конечном итоге все сводится к а) сопоставимому простому б) сопоставимому сложному.

Я понятия не имею, «изобрел» ли кто-то своего рода измеритель сложности языка.

По шкале от 0 до 10 я бы, вероятно, поставил C на 2 или 3, тогда как C ++ был бы между 8-10. Я бы сказал, что C ++ - один из самых сложных языков, но я не знаю, например, Ada, PL1 и т.п., так что, возможно, это не так сложно по сравнению с каким-либо другим языком.

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

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

Фридрих
источник
1

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

Это важно при подключении новой функции или компонента к старой и запутанной системе.

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

Calmarius
источник
0

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

В C ++ вы мыслите категориями объектов и их взаимосвязей. В C вы мыслите терминами API. Это как разница между днем ​​и 17.

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

Филипп
источник
0

Ниже приведены все причины, по которым может быть полезно ограничить проект C:

  • более быстрая компиляция, потому что язык намного проще
  • требует меньше поддержки во время выполнения, что делает его более подходящим для низкоуровневых сред
  • намного проще взаимодействовать с другими языками
  • поддерживает массивы переменного размера в стеке
  • легче читать код сборки, потому что нет искажения имени
  • позволяет легко комбинировать код, созданный разными компиляторами, поскольку это де-факто стандартный двоичный интерфейс приложения
DSH
источник