В данный момент на текущей работе я занимаюсь тем, что называется - высокоуровневое серверное программирование на С++. У меня уже есть все необходимые библиотеки низкого уровня и среднего (более того, если я отказываюсь по какой-то причине от готовой библиотеки, меня могут потом попросить это объяснить), и огромное количество библиотек высокого уровня, уровня бизнес-логики. К чему все это?
А вот к чему. Если разобраться, что я могу писать код вообще без С-шных штучек типа массивов, malloc/free, старого способа приведения типов, строчек с нулем на конце и т.д. Получается, что мой диалект С++ можно урезать на тему всего, что я перечислил. Просто убрать, и все.
И от этого будет только польза. Сколько ошибок потенциально я НЕ сделаю в арифметике указателей (ее просто не будет)? Вместо того, чтобы мотивировать человека "разумно использовать наследия С в С++", их надо просто выключить. Конечно, сразу сузится и круг решаемых задач, но мой, кстати, не самый узкий круг, можно покрыть таким вот урезанным в сторону "правильного" С++ диалектом С++.
Например, как мне кажется, функция memset() в мире С++ в целом годится разве что для обнуления. Использование какой-либо иной константы-заполнителя принципиально приближает нас к проблемам с памятью. Хотите, например, "эффективно" заполнить строку пробелами, и зарядите для этого memset(), а потом вам неожиданно придется работать с многобайтовыми кодировками, и этот пробел, записанный через memset(), может стать источником проблем.
Так что используйте алгоритм "fill_n()" вместо "memset()". Может быть неэффективен? Может, а может и нет. Зато уж точно безопасен с точки зрения типизации.
воскресенье, 20 июня 2010 г.
Подписаться на:
Комментарии к сообщению (Atom)
Верная позиция. Всегда нужно писать рабочий код, а не задумываться над оптимизацией/быстродействием. А штучки C++ (не Си) помогают писать код с меньшим кол-вом ошибок и меньшим кол-вом строк кода. Об оптимизации потом скажет профайлинг. :)
ОтветитьУдалитьАлександр, а зачем тогда использовать С++?
ОтветитьУдалитьПосле такого урезания получается джава с очень медленным компилятором и без сборки мусора.
А если еще и смарт-поинтером пользоваться, то и почти со сборкой мусора.
Но:
1. нет нормальной среды программирования, в которой можно было бы делать рефакторинг, как в IDEA/Eclipse на джаве
2. нет нормальных тулов для проверки быстродействия - требуют значительной "перекомпиляции"
3. медленный компилятор
4. из-за отсутствия run-time class-inspection и reflection тяжело делать мощную автоматизацию проверок.
Все эти вещи можно простить, когда нужны низкоуровневые штуки С. Если они не нужны - нет ни какой необходимости писать на С++ вообще.
Согласен с Nick по всем пунктам, кроме третьего: нормальные "тулы для проверки быстродействия" есть, и если слова vtune, valgrind и oprofile не известны, то писать на C++ просто не нужно.
ОтветитьУдалитьС fill_n и memset другая проблема. И тому и тому можно по ошибке задать диапазон, выходящий за пределы контейнера, который мы чистим, и перетереть кучу. А потом через много-много строчек кода разбираться, почему у нас exception на выделении/освобождении памяти.
ОтветитьУдалитьЗачем Java? Если уж речь зашла о managed environments, то тогда уж C# (Mono, если не Windows). Гораздо более красивый, развитый и наглядный язык как таковой.
ОтветитьУдалитьКстати, о рефакторинге. В видео про язык Go (см. предыдущий пост), авторы критикуют ООП языки типа C++/Java/C#/etc именно за болезнь рефакторинга. Если ты вдруг захотел потрогать базовые класса, вот и начинается массовый рефакторинг.
@ilja.golshtein: К сожалению, мы пользуемя только valgrind и он на порядок хуже тулов для джавы.
ОтветитьУдалитьВ нашем проекте, например, есть проблема скалабилити и ухудшения перформанса при заметном увеличении нагрузки. Так вот, при запуске с valgrind он падает от "перегрузки" на 20% от нагрузки которую тянет без valgrinda. И мало чего находит. А свой собственный фреймоворк, без инструментаций - находит.
Про другие тулы - спасибо, поизучаю.
@Александр: рефакторинг это не только перелопачивание иерархии классов. Даже переименовывание в С++ поддерживается всякими IDEs с грехом пополам. Video не смотрел пока, нельзя найти время на все, но моя собственная практика говорит мне, что без рефакторинга ни как. И мне тяжело поверить, что есть другая парадигма, где рефакторинг будет не нужен.
@Nick: Если рассматривать сложности с рефакторингом с чисто технической стороны, типа переименовать класс, убрать/добавить параметоры метода и т.д., то лично я полностью не согласен, что какое-либо IDE может радикально ускорить процесс. Я сейчас попеременно работаю в Eclipse для C++ и VIM с плагином NERD_tree. Не могу сказать, что в эклипсе я что-то делаю радикально быстрее, чем в VIM. То есть это просто вопрос, насколько хорошо освоен инструмент. То есть если я переименовал базовый класс, то пока не починю все дочерние классы, то просто проект не соберется. И врядли я тут могу ошибок наделать. А вот вопрос того, что мне впринципе надо зачем-либо трогать базовый класс только ради переименования, и почему это затрагивает остальные классы - это уже вопрос к ООП парадигме как таковой.
ОтветитьУдалитьХорошо, когда просят обосновать отказ от библиотеки.
ОтветитьУдалитьЯ встречался только с ситуациями, когда наоборот.
Этот комментарий был удален автором.
ОтветитьУдалитьПотроллить что-ли :-)
ОтветитьУдалитьА вот Линус Торвальдс утверждает, что C++ и все, что с ним связано, - sucks. И что лучше он будет писать с указателями и прочими радостями жизни=)
http://thread.gmane.org/gmane.comp.version-control.git/57643/focus=57918
Да, Линуса сложно упрекнуть, что он никогда не работал со сложными и большими проектами, которые длятся годами, работают на множестве архитектур и требуют постоянного развития и поддержки ;-).
ОтветитьУдалитьМне очень понравилась у него фраза
ОтветитьУдалитьQuite frankly, even if the choice of C were to do *nothing* but keep the C++ programmers out, that in itself would be a huge reason to use C.
Тем не менее, такие проблемы надо решать как-то по-другому.
/**
ОтветитьУдалить* @brief Fills the range [first,first+n) with copies of value.
* @ingroup mutating_algorithms
* @param first An output iterator.
* @param n The count of copies to perform.
* @param value A reference-to-const of arbitrary type.
* @return The iterator at first+n.
*
* This function fills a range with copies of the same value. For char
* types filling contiguous areas of memory, this becomes an inline call
* to @c memset or @ wmemset.
*/
http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01032_source.html