LINUX.ORG.RU
ФорумTalks

Почему на С++ пишут как на С?

 ,


0

4

Навеяно топиком http://slonik-v-domene.livejournal.com/142619.html

Вот зачем использовать функции из библиотеки С в проектах «на С++», когда можно использовать родные средства? Например в качестве типа строк использовать char* вместо std::string, гораздо более безопасного, вместо new / delete - malloc / free и так далее?

Чего я не понимаю? Может есть причины?

Конечно есть.
Уже хотя бы то причина, что подавляющее большинство плюсовиков писали до него на Си.
Неужели это так сложно?

Stahl ★★☆ ()

Когда как, несколько возможных причин:

  • код был раньше написан на C и полностью переписывать не стали
  • код был изначально сгеренирован (например, Fortran -> C) чем-то, что C++ генерировать не умеет
  • copy&paste из каких-нибудь справочных страниц, там чаще можно увидеть C чем C++
xaizek ★★★★★ ()

привычка. еще вспомни printf/etc. вместо потоков.

Lincor ()

Вам просто попадаются идиоты, а не C++ программисты

qrck ★★ ()

Потому что хотят писать именно на Си?

stevejobs ★★★☆☆ ()

давай мне сюда pure c++ классы для socket(), listen(), accept(), send(), recv()...

Stil ★★★★★ ()

Потому что «С с классами» нужен, а С++ - нет.

entefeed ☆☆☆ ()

Так себе код, конечно. Но, с другой стороны, форматный вывод Си удобнее угребищного поточного вывода Си++.

tailgunner ★★★★★ ()

Топик не читал.

char* иногда оказывается удобнее std::string. Он вполне предсказуем, не лезет в кучу (можно использовать в исключениях), совместим со всем, что можно представить, в т.ч. с Си.

new/delete нужны для работы с объектами, а malloc/realloc/free для работы с памятью. это типа разные вещи.

ien ()

Большая часть синтаксиса и стандартной библиотеки С является такой же родной частью С++, как и всякие шаблоны с ООП. Попробуй выкинуть из крестов Це, и они тут же станут нужны примерно так же как какой-нибудь брейнфак

Gvidon ★★★★ ()
Ответ на: комментарий от entefeed

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

arturpub ★★ ()

В некоторых случаях такая низкоуровщина оказывается быстрее и экономнее, чем классы STL.

Это не оправдывает уникумов, которые пишут любые C++ проекты на C.

// Не заметил особой сишности кода по ссылке, нормальный плюсовый код. Приемлемо.

E ★★★ ()
Последнее исправление: E (всего исправлений: 1)

Правильно так: «Почему на C++ пишут?»

Miguel ★★★★★ ()
Ответ на: комментарий от ien

Ну вот тебе один и тот жен код на С и С++. Пример искусственный, но все же.

char* str1 = "Hello";
char* str2 = (char*)malloc(32*1000);
memset(str2, 1, 32*1000);
strcat(str1, str2);
int i = strlen(sr1);
free(str2);

Упадет с сегфолтом.

std::string str1 = "Hello";
char* str2 = new char[32*1000];
memset(str2, 1, 32*1000);
str1 += str2;
int i = str1.size();
delete[] str2;
Работает.

LongLiveUbuntu ★★★★★ ()
Последнее исправление: LongLiveUbuntu (всего исправлений: 1)
Ответ на: комментарий от E

Не заметил особой сишности кода по ссылке, нормальный плюсовый код. Приемлемо.

	char * data = (char*) malloc(BUFFSIZE);
	if (!data) {
		free(data);
		close(sock);
		cerr << "malloc error" << endl;
		return;
	}

	int data_size = read(sock, data, BUFFSIZE);
	if (data_size <= 0) {
		std::cout << "error read data " << strerror(errno) << std::cout;
		free(data);
		close(sock);
		return;	
	}

Заметь как минимум дублирование кода при ошибочном завершении (в третий раз он дублируется в конце функции). Про несколько точек возврата из функции даже не говорю...

tailgunner ★★★★★ ()

1) Изначально код был написан на С.

2) Разработчик — бывший сишник.

3) Разработчик постигал искусство программирования по книге с названием "... C/C++".

aidan ★★★★ ()
Ответ на: комментарий от E

В некоторых случаях такая низкоуровщина оказывается быстрее и экономнее, чем классы STL.

Кресты в первую очередь умеют RAII. Против всяких шаблонов, иостримов и прочих исключений можно придумать отмазки, которые даже имеют смысл в некоторых из тех случаев, когда их озвучивают. Но против RAII можно выдвинуть только Лень, Привычки и Идиотизм.

const86 ★★★★★ ()

потому что могут

тебе больше нравится код от покусанных Александреску индивидов?

Harald ★★★★★ ()
Ответ на: комментарий от const86

Я полностью с этим согласен, но я про RAII не писал ничего.

E ★★★ ()

Например std::string имеет такую проблему как «скрытые аллокации». Вместо явного «выдели мне память» оно может сделать это без твоего ведома. Что ведёт к фрагментации памяти или ещё к каким проблемам.

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

ranka-lee ()
Ответ на: комментарий от Lincor

Потоки это не более чем забавная демонстрация возможностей C++. Как и весь STL. Использовать можно, но только если очень хорошо всё понимаешь.

ranka-lee ()
Последнее исправление: ranka-lee (всего исправлений: 1)

А вообще впечатление что код писало минимум 2 человека, причём он был портирован с чистого C.

ranka-lee ()

Да потому что половина учебников называется "..... C/C++ ....."

AlexVR ★★★★★ ()
Ответ на: комментарий от LongLiveUbuntu

Упадет с сегфолтом.

Может быть потому, что использовать UB нехорошо?

buddhist ★★★★★ ()

Что по ссылке не знаю, но иногда для скорости, т.к. плюсовые потоки I/O получились не такими быстрыми как хотелось бы :}

Deleted ()
Ответ на: комментарий от tailgunner

Заметь как минимум дублирование кода при ошибочном завершении (в третий раз он дублируется в конце функции).

Эмм... А при чем здесь вообще C/C++? То, что ты перечислил - логика программы, и от языка (C/C++) она не зависит. И на С и на С++ можно написать так, а можно по-другому.

дублирование кода

Кстати, как бы ты его изменил? Я вот придумал парочку вариантов, но они нетривиальны: 1) if с дикой конструкцией, 2) вывести нужное в блок, а обработку ошибки - в конец функции, но так страдает читаемость 3) запихнуть все в макрос - костыльно. 4) запихнуть нужное в деструктор каког-то объекта - сомнительный способ. Дальше не думал. Сам не люблю дублирующийся код, но иногда бывает нужно.

Про несколько точек возврата из функции даже не говорю...

И в чем проблема в нескольких точках возврата?

Да, по теме:

Почему на С++ пишут как на С?

Потому что цель - не чистота кода, а чтобы работало и было более-менее читабельно.

Kroz ★★★★★ ()
Последнее исправление: Kroz (всего исправлений: 1)
Ответ на: комментарий от Gvidon

Не стандарт. Доп. либа. А header-only asio нуждалась в пачке костылей (дефайнов), когда я её последний раз тыкал

Stil ★★★★★ ()
Ответ на: комментарий от Kroz

вывести нужное в блок, а обработку ошибки - в конец функции, но так страдает читаемость

Для этого придумали исключения

Stil ★★★★★ ()

Потому что большинство пишет на Си с классами, а не на тру C++.

bluesman ()
Ответ на: комментарий от Stil

Для этого придумали исключения

Хотел было возразить, но, подумав - соглашусь :)

Kroz ★★★★★ ()
Ответ на: комментарий от Kroz

Заметь как минимум дублирование кода при ошибочном завершении (в третий раз он дублируется в конце функции).

Эмм... А при чем здесь вообще C/C++?

«Причем» качество кода.

То, что ты перечислил - логика программы, и от языка (C/C++) она не зависит

В прилично написанной программе на Си++ файловый дескриптор закрывался бы RAII. Да и блок памяти, вероятно, тоже освобождался бы RAII.

И в чем проблема в нескольких точках возврата?

Код становится труднее для понимания и модификации.

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

Эмм... А при чем здесь вообще C/C++?

Причем» качество кода.

Это не качество кода, а качество алгоритма. Различаешь?

В прилично написанной программе на Си++ файловый дескриптор закрывался бы RAII. Да и блок памяти, вероятно, тоже освобождался бы RAII.

Что такое RAII?

Код становится труднее для понимания и модификации.

Как раз он становится проще для понимания. Где ошибка - выход; или исключение, как товарищ вверху предложил. Логично, ожидаемо, проще.

Kroz ★★★★★ ()
Ответ на: комментарий от LongLiveUbuntu

Это разный код, именно поэтому и результат разный =)

Я не очень понимаю, к чему этот пример. Тезис-то в чем? Что std::string богаче по возможностям, чем char*, и сам выделяет память? Было бы странно, если бы это было наоборот.

Но есть ситуации, когда char* гораздо лучше. Самая очевидная, это когда в char* массив байтов, а не символов. Далее, как уже писали выше, убогое плюсовое форматирование. Поэтому для разных задач — разные средства.

ien ()
Ответ на: комментарий от tailgunner

Код становится труднее для понимания и модификации.

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

Мне гораздо тяжелее было бы его читать в таком виде:

result = ...;
if(...)
{
   ...
   if(...)
   {
       ...
       if(...)
       {
           result = ...;
       }
   }
}
return result;
ien ()
Ответ на: комментарий от Kroz

Это не качество кода, а качество алгоритма. Различаешь?

Это именно качество кода.

Что такое RAII?

Жаль, что ты не задал этот вопрос сразу.

Как раз он становится проще для понимания. Где ошибка - выход

У меня нет желания заниматься твоим образованием. Проще так проще.

tailgunner ★★★★★ ()
Ответ на: комментарий от LongLiveUbuntu

C++ вариант ВСЕГДА работает или только тогда, когда после str2 встречается ноль?

vromanov ★★ ()
Ответ на: комментарий от ien

Мне гораздо тяжелее было бы его читать в таком виде:

Поэтому в Си++ использут RAII, а в Си - goto.

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

Но, с другой стороны, форматный вывод Си удобнее угребищного поточного вывода Си++.

+1. Это было первое, о чем я подумал, читая топик. Хоть printf и не без проблем, но он явно удобнее.

Pavval ★★★★★ ()
Ответ на: комментарий от ranka-lee

За использование boost во многих местах отрывают руки.

А за использование той части буста, что почти без изменений вошла в С++11 - тоже отрывают? И вообще, какая аргументация?

Pavval ★★★★★ ()
Ответ на: комментарий от Lincor

Пример некорректный. printf используют не из-за привычек, а из-за удобства. Например, чтобы распечатать потоками какой-нибудь double в формате %2.8le на потоках надо очень сильно из%%нуться.

Reset ★★★★★ ()
Ответ на: комментарий от tailgunner
	char * data = (char*) malloc(BUFFSIZE);
	if (!data) {
		free(data);

LOL. Нахрена он освобождает нулевой указатель? Понятно, что ошибки не будет, но смысл?

WatchCat ★★★★★ ()
Ответ на: комментарий от vromanov

Всегда, ибо не происходит перезаписи данных, находящихся в памяти рядом с str1. Будет получена новая корректная строка.

А вот в С - как повезет.

LongLiveUbuntu ★★★★★ ()
Ответ на: комментарий от WatchCat

Лал, прикол еще в том, что NULL возвращается если malloc() не может выделить память, так что free() тут бессмысленно.

LongLiveUbuntu ★★★★★ ()
Ответ на: комментарий от tailgunner

Чтож, некоторые люди приходят на форум чтобы узнать что-то новое, да и другим помочь. А некоторые - чтобы почесать ЧСВ. Похоже, ты из последних.

Kroz ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.