С-программер (Олег К.) и С++ программер (Vain) солидарно считают что программирование на С — мазохизм.
С некоторыми оговорками я с ними в общем-то согласен, но тем не менее существует стереотип что С — безусловный мазохизм! Вопрос в том почему имено вы так считаете, или не считаете?
Здравствуйте, adontz, Вы писали:
AS>>Вопрос в том почему имено вы так считаете, или не считаете? A>Выгоды (дополнительная гибкость, дополнительная портируемость, и т.д.) не адекватны трудозатратам (утечки ресурсов, слабая типизация).
Относительно утечки ресурсов не всё так просто. В С есть свои техники аналогичные идеоме умных указателей и RAII. К тому же, на доступных версиях компилятора С++ до определённого момента (где-то в середине 90-ых если мне склероз не изменяет) было крайне тяжело контролировать ресурсы. В этом плане он от С не сильно отличался. Щас с Modern C++ это делать весьма несложно. Но и в С вобщем-то тоже =) Я постараюсь на неделе написать и про это.
Является ли минусом слабая типизация — это вообще сложный вопрос. Именно для С — это гигантский плюс, ИМХО =)
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>>>Вопрос в том почему имено вы так считаете, или не считаете? AS>Относительно утечки ресурсов не всё так просто. В С есть свои техники аналогичные идеоме умных указателей и RAII.
Существование техник и удобство их использования разные вещи.
AS>К тому же, на доступных версиях компилятора С++ до определённого момента (где-то в середине 90-ых если мне склероз не изменяет) было крайне тяжело контролировать ресурсы.
Что, деструкторы не работали?
AS>Является ли минусом слабая типизация — это вообще сложный вопрос. Именно для С — это гигантский плюс, ИМХО =)
Вопрос только в том, оправдывает ли удобство в 2% случаев, когда это надо, проблемы в 98% случаев, когда это не надо.
A>Что, деструкторы не работали?
Тяжело было на каждый чих деструкторы писать =)
AS>>Является ли минусом слабая типизация — это вообще сложный вопрос. Именно для С — это гигантский плюс, ИМХО =) A>Вопрос только в том, оправдывает ли удобство в 2% случаев, когда это надо, проблемы в 98% случаев, когда это не надо.
А что это действительно даёт столько проблем?!
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>>>Является ли минусом слабая типизация — это вообще сложный вопрос. Именно для С — это гигантский плюс, ИМХО =) A>>Вопрос только в том, оправдывает ли удобство в 2% случаев, когда это надо, проблемы в 98% случаев, когда это не надо. AS>А что это действительно даёт столько проблем?!
Всегда есть человеческий фактор, вероятность ошибки. Венгерская нотация — очевидный костыль, позволяющий визуально контроллировать типы вместо компилятора. Если нет проблемы со случайным использованием слабой типизации, то зачем венгерская нотация?
Здравствуйте, adontz, Вы писали:
A>Если нет проблемы со случайным использованием слабой типизации, то зачем венгерская нотация?
Понятия не имею, и никогда не использовал. Вы считаете что именно для этого?
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>С некоторыми оговорками я с ними в общем-то согласен, но тем не менее существует стереотип что С — безусловный мазохизм! Вопрос в том почему имено вы так считаете, или не считаете?
Смотря для каких задач его применять. Для низкоуровневого программирования, Си отличный инструмент. А для более высокоуровневого программирования, мазохизм. Я на Си программировал разные микроконтроллеры, для таких задач, он действительно хорош. Ну или для программ близких к железу, а также для написания критичных к скорости участков кода. А вот в веб-прогрограммировании никто в здравом уме Си использовать не будет. И поэтому я не могу сказать, что Си — безусловный мазохизм, все как раз зависит от условий, в которых мы находимся.
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
С-программер (Олег К.) и С++ программер (Vain) солидарно считают что программирование на С — мазохизм.
AS>С некоторыми оговорками я с ними в общем-то согласен, но тем не менее существует стереотип что С — безусловный мазохизм! Вопрос в том почему имено вы так считаете, или не считаете?
Странно было бы не соглашаться с очевидным.
Потому что практически все, что можно написать на Си, можно написать и на С++, но не наоборот. За исключением некоторых С99-фич, собственно (некоторых — потому что многие фичи уже вошли в новый стандарт и/или поддерживаются компиляторами подпольно уже сейчас, например, restrict, variadic macros etc).
Все твои трюки со свичами будут прекрасно работать и в С++.
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>Здравствуйте, adontz, Вы писали:
AS>>>Вопрос в том почему имено вы так считаете, или не считаете? A>>Выгоды (дополнительная гибкость, дополнительная портируемость, и т.д.) не адекватны трудозатратам (утечки ресурсов, слабая типизация).
AS>Относительно утечки ресурсов не всё так просто. В С есть свои техники аналогичные идеоме умных указателей и RAII. К тому же, на доступных версиях компилятора С++ до определённого момента (где-то в середине 90-ых если мне склероз не изменяет) было крайне тяжело контролировать ресурсы. В этом плане он от С не сильно отличался. Щас с Modern C++ это делать весьма несложно. Но и в С вобщем-то тоже =) Я постараюсь на неделе написать и про это.
AS>Является ли минусом слабая типизация — это вообще сложный вопрос. Именно для С — это гигантский плюс, ИМХО =)
reinterpret_cast в С++ замечательно убивают любую типизацию там, где это вдруг потребовалось
Здравствуйте, Alexéy Sudáchen, Вы писали:
A>>Если нет проблемы со случайным использованием слабой типизации, то зачем венгерская нотация? AS>Понятия не имею, и никогда не использовал. Вы считаете что именно для этого?
Да, я думаю что сейчас она используется именно для этого (хотя придумывалась для другого).
Здравствуйте, jazzer, Вы писали:
J>Странно было бы не соглашаться с очевидным.
Ну для меня это совсем не очевидно =)
J>Потому что практически все, что можно написать на Си, можно написать и на С++, но не наоборот. За исключением некоторых С99-фич, собственно (некоторых — потому что многие фичи уже вошли в новый стандарт и/или поддерживаются компиляторами подпольно уже сейчас, например, restrict, variadic macros etc).
Ну далеко не всё. В С в отличии от С++ void* приводится к любому другому указателю. Это вроде бы незначительное отличие может в корне менять структуру программы. В скобках запутаешся то же самое писать на плюсах.
On 20.02.2011 11:13, Alexéy Sudáchen wrote:
> С некоторыми оговорками я с ними в общем-то согласен, но тем не менее существует > стереотип что С — безусловный мазохизм!
Программировать на С -- безусловный мазохизм, потому что
С++ делает кучу проверок за тебя, в то время как С оставляет
тебя на едине со своими проблемами. А разницы в коде или сборке
нет никакой.
Можно писать на С++ не используя классы, шаблоны и пр. , уже будет лучше.
Здравствуйте, MasterZiv, Вы писали:
MZ>Программировать на С -- безусловный мазохизм, потому что MZ>С++ делает кучу проверок за тебя, в то время как С оставляет MZ>тебя на едине со своими проблемами. А разницы в коде или сборке MZ>нет никакой.
То есть вы хотите сказать что если я пишу на С++ тот же самый код что и на С (а именно без шаблонов и классов), то я получаю некие дополнительные проверки, который магически защищают мой код?! Это интересно какие?
MZ>Можно писать на С++ не используя классы, шаблоны и пр. , уже будет лучше.
Здравствуйте, __lambda__, Вы писали:
___>Смотря для каких задач его применять. Для низкоуровневого программирования, Си отличный инструмент. А для более высокоуровневого программирования, мазохизм. Я на Си программировал разные микроконтроллеры, для таких задач, он действительно хорош. Ну или для программ близких к железу, а также для написания критичных к скорости участков кода. А вот в веб-прогрограммировании никто в здравом уме Си использовать не будет. И поэтому я не могу сказать, что Си — безусловный мазохизм, все как раз зависит от условий, в которых мы находимся.
Ну хорошо, вы повторили своими словами высказывание ставшее причиной это обсуждения. С некоторыми исключениями конечно. Однако почему вы так считаете?
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>То есть вы хотите сказать что если я пишу на С++ тот же самый код что и на С (а именно без шаблонов и классов), то я получаю некие дополнительные проверки, который магически защищают мой код?! Это интересно какие?
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>Ну хорошо, вы повторили своими словами высказывание ставшее причиной это обсуждения. С некоторыми исключениями конечно. Однако почему вы так считаете?
Странно, я думал, что опроверг, то самое высказывание. То высказывание, где утверждается, что программирование на Си, это безусловный мазохизм. И вроде как даже обосновал свою точку зрения тем, что условия разные бывают.
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Здравствуйте, FR, Вы писали:
FR>Здравствуйте, Alexéy Sudáchen, Вы писали:
FR>
FR>void (*FPtr)(void) = Tst;
FR>
Ну, я уверен что С ты знаешь и выделенное пропустил намеренно, как и -Wall -Werror. Ещё вырианты есть?
Я в С++ тоже могу гору багов с опечатками набрать, несмотря на его жёсткую типизацию и использование всяких песочниц а-ля STL. =)))
Здравствуйте, __lambda__, Вы писали:
___>Странно, я думал, что опроверг, то самое высказывание. То высказывание, где утверждается, что программирование на Си, это безусловный мазохизм. И вроде как даже обосновал свою точку зрения тем, что условия разные бывают.
Согласен. Я неправильно выразился.
Я имел в виду почему мазохизм остаётся применительно к задачам не связанным с низкоуровневым кодом?
Re: Потому что одинаковый результат требует больших трудозат
int somefunc()
{
int flags;
do1();
flags = get_and_disable_interrupts();
if (do2())
{
restore_interrupts(flags);
return 1;
}
do3();
restore_interrupts(flags);
return 2;
}
Он очевидно запрещает прерывания, делает некоторые критичные вычисления и разрешает их обратно.
Теперь посмотрим, как С++ упростит нам жизнь. Один раз пишем такое:
class InterruptHolder
{
int m_Flags;
public:
InterruptHolder() {m_Flags = get_and_disable_interrupts();}
!InterruptHolder() {restore_interrupts(m_Flags);}
}
Теперь, somefunc() выглядит в полтора раза короче:
int somefunc()
{
do1();
InterruptHolder holder;
if (do2())
return 1;
do3();
return 2;
}
Плюс, если на Си мы могли забыть сделать restore_interrupts() перед очередным return и поиметь "странный висяк", то здесь этим занимается компилятор, а мы ограничиваемся созданием InterruptHolder, запрещая прерывания до конца текущей scope.
С отключенными исключениями и современным gcc (4.x) бинарники для варианта на Си и варианта на С++ будут идентичны (проверялось на AVR, ARM, x86 и еще паре пдатформ).
В сухом остатке имеем: получили бинарно эквивалентное решение, написав меньшее количество кода (не считая однократно реализованный InterruptHolder), плюс, застраховались от бага с забыиым restore(). Из минусов — компиляция займет на секунду больше.
Махровые сишники щас придут и скажут, что С++ есть не для всех платформ, на что я отвечу, что если производитель вашего процессора в 2011 году тянет свой компилятор, вместо того, чтобы портировать туда GCC, у производителя плохо с головой и с этой платформы надо бежать, ибо иначе утонете в глюках и большую часть времени будете заниматься ручной оптимизацией. Хитровывернутые DSP и ASIP с контекстнозависимыми регистрами — исключение, но там и от Си толку мало.
Здравствуйте, Wissenschaftler, Вы писали:
W>Он очевидно запрещает прерывания, делает некоторые критичные вычисления и разрешает их обратно. W>Теперь посмотрим, как С++ упростит нам жизнь. Один раз пишем такое:
И что вам мешает сделать то же самое на Си? Я в общем-то показал как.
Re[3]: Потому что одинаковый результат требует больших трудо
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>Здравствуйте, Wissenschaftler, Вы писали:
W>>Он очевидно запрещает прерывания, делает некоторые критичные вычисления и разрешает их обратно. W>>Теперь посмотрим, как С++ упростит нам жизнь. Один раз пишем такое: AS>И что вам мешает сделать то же самое на Си? Я в общем-то показал как.
1) Хуже читаемость. Многострочные #define в разы усложняют отладку, анализ сообщений об ошибках и анализ ассемблерного кода с аннотациями.
2) Я так и не понял, как ваш вариант на чистом Си реализует вызов release() после того, как защищенный код сделает return.
1 и 3 объяснения не требуют, а под С с классами я имею в виду подмножество С++, не включающее в себя
-исключения
-полиморфизм.
-STL
и может кое-что еще по мелочам.
(заметьте, наследование невиртуальное я не убрал)
Иными словами, это именно С с иной организацией данных, то есть не хаотический набор функций и структур, а организованный с помощью классов.
Оверхед от С с классами по сравнению с чистым С — полный нуль. В С++ есть малюсенький оверхед, связанный с виртуальными вызовами через vtable, а здесь и его нет.
Так вот, С с классами как я его определил здесь имеет явное преимущество по сравнению с чистым С. Объяснять, я думаю, не надо.
Ну а кроме того, если писать на С с классами, то при необходимости можно использовать и что-то от полного С++. Нет ведь такого языка — С с классами
AS>существует стереотип что С — безусловный мазохизм! Вопрос в том почему имено вы так считаете, или не считаете?
Как всегда, без контекста вопрос не имеет смысла. Всё зависит от задачи. Если речь идёт о сложной системе "общего назначения", то ООП предоставляет очевидные преимущества по сравнению со "структурным программированием". Оперировать объектами выгоднее, чем функциями. Это позволяет безболезненно откладывать многие важные решения на более поздние сроки в жизни проекта, что уменьшает вред от проектных ошибок (чем раньше допущена ошибка, тем труднее исправлять).
Тут я предполагаю, что C используется традиционно, ведь и на C можно программировать в стиле ООП. Только это потребует больших усилий. Например, во многих видах рефакторинга нельзя будет довериться компилятору, загнав некий интерфейс в private, и потом тупо перекомпилировать, исправляя места, которые не компилируются.
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>С некоторыми оговорками я с ними в общем-то согласен, но тем не менее существует стереотип что С — безусловный мазохизм! Вопрос в том почему имено вы так считаете, или не считаете?
Я, например, считаю, что программирование на C++ — мазохизм. В отличии от программирования на Си
Re[4]: Потому что одинаковый результат требует больших трудо
Здравствуйте, Wissenschaftler, Вы писали:
W>1) Хуже читаемость. Многострочные #define в разы усложняют отладку, анализ сообщений об ошибках и анализ ассемблерного кода с аннотациями. W>2) Я так и не понял, как ваш вариант на чистом Си реализует вызов release() после того, как защищенный код сделает return.
Первое не сильно отличается от варианта с плюсами. Особенно в контексте gcc используемого на встроенных платформах. Кстати можете и в одну строчку написать =) Сути дела это не меняет. К тому же вы привели ну очень рафинированный пример. В реальном случае синхры при таком использовании гардов (они обычно с параметром) могут быть очень интересные спецэффекты, и вы наверняка про это знаете.
А относительно второго. Никак. Не надо делать return из глубин блока. Это в этом простом примере всё очевидно, а в более сложном такая техника программирования сама по себе источник ошибок.
int somefunc()
{
int result = 2;
do1();
__Disable_Intr
{
if ( do2() )
result = 1;
else
do3();
}
return result;
}
делает абсолютно то же смое но условность do3 при этом совершенно очевидна. Уже не говоря про отладку и анализ кода ассемблера.
Так что если вопрос только в технике кодирования... ну это вопрос да. На очень большой флейм. Принципиальной же проблемы сделать рюшечки как в С++ нет никакой.
Здравствуйте, adontz, Вы писали:
AS>>Вопрос в том почему имено вы так считаете, или не считаете?
A>Выгоды (дополнительная гибкость, дополнительная портируемость, и т.д.) не адекватны трудозатратам (утечки ресурсов, слабая типизация).
В каком смысле, слабая типизация? Типизация в ANSI Си точно такая же, как в C++, почему в одном случае она слабая, а в другом — нет?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Так вот, С с классами как я его определил здесь имеет явное преимущество по сравнению с чистым С. Объяснять, я думаю, не надо.
Почему же. Я бы очень даже хотел послушать. Дело в том что мои программы на С вполне себе используют ООП, хотя и не такой как в С++ и даже не такой как в книжках. Это ближе к Objective но без специфического 'препроцессора'.
Вот мне и интересно почему 'С с классами' безусловно лучше чем С.
Здравствуйте, Kswapd, Вы писали:
K>Тут я предполагаю, что C используется традиционно, ведь и на C можно программировать в стиле ООП. Только это потребует больших усилий. Например, во многих видах рефакторинга нельзя будет довериться компилятору, загнав некий интерфейс в private, и потом тупо перекомпилировать, исправляя места, которые не компилируются.
Ну я пишу на С с объектами и без особых усилий =) Да всё компилятор конечно не видит, однако после активного использования питона я стал писать так что это меня вообще никак не анноит, при том что в С типизация и проверки в отличии от есть. Максимум на что я могу нарваться — на исключение 'метод не найден'.
Тут надо хорошо понимать что C++ это не совсем ООП, а некая его кастрация. =) Можно ведь писать и иначе. И на С это делать ИМХО проще чем на С++.
Здравствуйте, __lambda__, Вы писали:
___>Потому что, как бы это ни банально звучало, высокоуровневые задачи лучше решать с помощью соответствующих инструментов.
Дык, а что вы понимаете под высокоуровнивостью?! Чего такого нет в С что должно быть в таком инструменте?
AS>Ну я пишу на С с объектами и без особых усилий =)
Значит, ты очень способный программист . А для таких туповатых ремесленников, как я, желательно помнить поменьше, и делегировать компилятору побольше рутинной работы (вроде поддержки таблицы виртуальных функций).
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>Дык, а что вы понимаете под высокоуровнивостью?! Чего такого нет в С что должно быть в таком инструменте?
Ой, да много чего, до утра можно перечислять. Ну так, навскидку: garbage collector, pattern matching, ADT (algebraic data type), metaprogramming, list comprehension, higher-order functions, etc.
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Здравствуйте, __lambda__, Вы писали:
AS>>Дык, а что вы понимаете под высокоуровнивостью?! Чего такого нет в С что должно быть в таком инструменте? ___>Ой, да много чего, до утра можно перечислять. Ну так, навскидку: garbage collector, pattern matching, ADT (algebraic data type), metaprogramming, list comprehension, higher-order functions, etc.
О как! Тогда другой вопрос. И для каких 'реальных' задач нужен инструмент всем этим обладающий?! Просто у меня таких нет, так что тут чистой воды любопытство.
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>Вот мне и интересно почему 'С с классами' безусловно лучше чем С.
1. Организация методов по классам. Организация полей есть и в struct из С, а методов — нет.
2. Передача экземпляра по this. Гораздо сложнее передать не то, что надо.
3. Наследование. Если мне нужно иметь некую структуру и ее расширенный вариант, то не придется все переписывать. Методы для базовой структуры можно без изменений применять для расширенной. Например "заголовок — пакет" (в предположении, что в начале пакета всегда сидит заголовок)
4. Конструкторы и деструкторы.
5. template — это все же намного мощнее, чем препроцессор, и удобнее.
6. Ссылки иногда удобнее указателей. Хотя я предпочитаю указатели, если возможен выбор.
7. Перегрузка стандартных операций — пустяк, а приятно.
8. Все же лучше new-delete, чем malloc-free
9. Более строгая типизация. Хотя порой раздражает.
Если посидеть и подумать, можно, наверное еще что-то боавить.
Отмечу и один недостаток. Деструктор. В С закрывающая фигурная скобка у меня абсолютно никаких эмоций не вызывает, код ей не соответствует. В С++ на закрывающую фигурную может оказаться повещенным такое количество действий, что мало не покажется. Иными словами, в С для выполнения чего бы то ни было надо именно в этом месте написать код, а в С++ он вызовется, хотя именно в этой строке ничего не написано.
Здравствуйте, Pzz, Вы писали:
Pzz>>>Типизация в ANSI Си точно такая же, как в C++, почему в одном случае она слабая, а в другом — нет? A>>Это не так. Pzz>Это не аргумент
Ну, как тебе такой аргумент: То что в С — предупреждение, в С++ — ошибка.
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>Первое не сильно отличается от варианта с плюсами. Особенно в контексте gcc используемого на встроенных платформах. Кстати можете и в одну строчку написать =) Сути дела это не меняет. К тому же вы привели ну очень рафинированный пример. В реальном случае синхры при таком использовании гардов (они обычно с параметром) могут быть очень интересные спецэффекты, и вы наверняка про это знаете.
Например? В gcc4 спецэффектов не наблюдал. Пример "запретить прерывания, проверить три-пять условий, вернуть ошибку если хотя бы одно выполнилось, проставить флаг, вернуть STATUS_SUCCESS" вполне себе практический.
AS>А относительно второго. Никак. Не надо делать return из глубин блока. Это в этом простом примере всё очевидно, а в более сложном такая техника программирования сама по себе источник ошибок.
Ну вот как только компилятор начинает говорить мне, что надо, а что нет — начинается мазохизм. В идеале, отличие guarded-программы от не-guraded должно состоять в одной строчке, какбэ говорящей компилятору "сделай этот кусок кода guarded". Если начинаются всякие танцы с бубном а-ля заменяем return на result = x; break;, вставляем goto, добавляем кучу фигурных скобок и т.п. — начинается мазохизм.
AS>
AS>int somefunc()
AS> {
AS> int result = 2;
AS> do1();
AS> __Disable_Intr
AS> {
AS> if ( do2() )
AS> result = 1;
AS> else
AS> do3();
AS> }
AS> return result;
AS> }
AS>
AS>делает абсолютно то же смое но условность do3 при этом совершенно очевидна. Уже не говоря про отладку и анализ кода ассемблера.
Только если do3() состоит из нескольких строчек, начинаются танцы со скобками.
AS>Так что если вопрос только в технике кодирования... ну это вопрос да. На очень большой флейм. Принципиальной же проблемы сделать рюшечки как в С++ нет никакой.
Сделать эквивалентные по юзабельности рюшечки — есть. И вы сами это только что показали, введя ограничения на то, что должно быть внутри блока. Принципиальной же проблемы быть не может по определению, т.к. оба языка — тьюринг-полные. Но это не означает, что тьюринг-полный, скажем, brainfuck будет настолько же хорош для разработки, как тьюринг-полный C++.
Короче, то, что из Си с помощью макросов, хаков и терпения, запилить свой С++ — не секрет. Вопрос, зачем это делать, если есть готовый язык.
Здравствуйте, Pavel Dvorkin, Вы писали:
AS>>Вот мне и интересно почему 'С с классами' безусловно лучше чем С.
Ну то есть если мы используем ООП а-ля C++ то С++ удобнее. Да, так и есть. =) Здесь не с чем спорить.
Однако есть ООП: во-первых без классов, во-вторых без VMT. И мне он, к примеру, более симпатичен. Остальное это С++-way.
Я ещё раз хочу обратить внимание — если повторять на С архитектуру С++, то С++ будет удобнее. Это очевидно. =)
PD>Отмечу и один недостаток. Деструктор. В С закрывающая фигурная скобка у меня абсолютно никаких эмоций не вызывает, код ей не соответствует. В С++ на закрывающую фигурную может оказаться повещенным такое количество
Ну, это достаточно спорно. Я не считаю это недостатком. Кто-то даже считает достоинством. В некотором смысле вопрос привычки.
AS>Ну, я уверен что С ты знаешь и выделенное пропустил намеренно, как и -Wall -Werror. Ещё вырианты есть?
Нет Си я знаю довольно посредственно, мало на чистом Си писал, но немало переносил как с Си на C++ так и
наоборот, и такие ошибки там делаются запросто. C++ не на шаблонах такое не пропускает.
AS>Я в С++ тоже могу гору багов с опечатками набрать, несмотря на его жёсткую типизацию и использование всяких песочниц а-ля STL. =)))
Опечатки только в шаблонах проходят, в остальном типизация в С++ намного жестче.
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>О как! Тогда другой вопрос. И для каких 'реальных' задач нужен инструмент всем этим обладающий?! Просто у меня таких нет, так что тут чистой воды любопытство.
Далеко за примерами ходить не надо. Посмотрел на исходное
твое сообщение. Такой проблемы, для примера, если взять ту же Java, не стоит, там для этого есть конструкция synchronized. Аналогично для C# есть конструкция lock.
Но и эти решения являются довольно низкоуровневыми. Настоящие джедаи используют STM (software transactional memory), Actor model, etc.
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Я бы так сказал. Есть не 2, а 3 языка
PD>1. С как он есть PD>2. С с классами. PD>3 С++
Скорее 4, твой третий пункт делится на 2:
3. С++ с исключениями, классами, STL и шаблонами используемыми только для обобщенного программирования.
4. C++ с шаблонами используемыми для метапрограммирования.
а с выходом нового стандарта и все пять
Re[6]: Потому что одинаковый результат требует больших трудо
Здравствуйте, Wissenschaftler, Вы писали:
W>Например? В gcc4 спецэффектов не наблюдал. Пример "запретить прерывания, проверить три-пять условий, вернуть ошибку если хотя бы одно выполнилось, проставить флаг, вернуть STATUS_SUCCESS" вполне себе практический.
С конструкцией
{
Guard x(guarded);
а тут чего-то делаем
}
Никогда не сталкивались?!
W>Ну вот как только компилятор начинает говорить мне, что надо, а что нет — начинается мазохизм. В идеале, отличие guarded-программы от не-guraded должно состоять в одной строчке, какбэ говорящей компилятору "сделай этот кусок кода guarded". Если начинаются всякие танцы с бубном а-ля заменяем return на result = x; break;, вставляем goto, добавляем кучу фигурных скобок и т.п. — начинается мазохизм.
Это вопрос в том надо ли вам что-то заменять. Мне нет, у меня практически весь код так написан.
А вот обьектная модель С++ и его заморочки с типизацией меня не устраивают. Вы разве совершенно не замечаете множеством сложностей с самим языком, что возникают как только мы начинаем активно использовать языковые возможности для управления ресурсами? В результате мифический 'мазохизм' С перерастает в совершенно реальный 'анонизм' С++. Однако это уже достаточно сложно заметить оставаясь в рамках С++. При том что граблей там до и больше. Только запрятаны они более изысканно =) ИМХО конечно, однако моё.
W>Только если do3() состоит из нескольких строчек, начинаются танцы со скобками.
Э... ну если вы и на скобках и функциях экономите =) Могу только пожелать вам удачи.
W>Короче, то, что из Си с помощью макросов, хаков и терпения, запилить свой С++ — не секрет. Вопрос, зачем это делать, если есть готовый язык.
Наверное для того чтобы иметь другой язык? Сходство с С++ тут чисто идиоматическое. Даже синтаксически наши варианты как вы сами заметили сильно расходятся.
Здравствуйте, FR, Вы писали:
AS>>Я в С++ тоже могу гору багов с опечатками набрать, несмотря на его жёсткую типизацию и использование всяких песочниц а-ля STL. =))) FR>Опечатки только в шаблонах проходят, в остальном типизация в С++ намного жестче.
Ну да, ну да. Совсем тривиальный пример —
struct A { int a; };
struct B : A { int b; };
B func() { return B(); }
A a = func();
А уж чего такой код в реальности натворить может =)
Здравствуйте, __lambda__, Вы писали:
AS>>О как! Тогда другой вопрос. И для каких 'реальных' задач нужен инструмент всем этим обладающий?! Просто у меня таких нет, так что тут чистой воды любопытство. ___>Далеко за примерами ходить не надо. Посмотрел на исходное
твое сообщение. Такой проблемы, для примера, если взять ту же Java, не стоит, там для этого есть конструкция synchronized. Аналогично для C# есть конструкция lock.
Это не задача. Это элемент реализации. Как бы программы пишутся таки для какой-то более нужной цели чем мутексы лочить. Или вы хотите сказать что если нужно синхронизировать пру потоков, то самое лучшее решение залезть в JVM?! ИМХО, конечно, но подход весьма специфический.
Таки какие реально задачи, хотя бы в вашей практике, требовали всего того перечисленного богатства высокоуровневых возможностей?!
Здравствуйте, Alexéy Sudáchen, Вы писали:
PD>>Отмечу и один недостаток. Деструктор. В С закрывающая фигурная скобка у меня абсолютно никаких эмоций не вызывает, код ей не соответствует. В С++ на закрывающую фигурную может оказаться повещенным такое количество
AS>Ну, это достаточно спорно. Я не считаю это недостатком. Кто-то даже считает достоинством. В некотором смысле вопрос привычки.
Нет, это серьезнее.
Одно из свойств чистого С — за ним "видно" ассемблер. Это не значит, что написав что-то на С, я мыслено компилирую это на асм. Нет. Но я всегда примерно представляю себе, что получится из этой С-конструкции. Речь идет не о конкретных ассемблерных командах (тут я могу и ошибиться), а о, так сказать, общем наборе асм-инструкций для реализации этой конструкции. Так вот, в С этот принцип выполняется практически всегда, не случайно его иногда называют высокоуровневым ассемблером.
Когда я ассемблер вижу, я уверен в том, что делаться будет только то, что я замыслил, и только так, как я замыслил, причем в пределах любого фрагмента. И ничего больше, если , конечно, компилятор не писали идиоты.
Деструкторы, вызываемые в неизвестном мне порядке при выходе на }, эту картину несколько портят. Портит ее и перегрузка операторов, когда банальный + означает что-то такое, что никак из этого знака плюса не следует. Но, пожалуй, это и все. Остальное в моем "С с классами" эту парадигму не нарушает.
Здравствуйте, FR, Вы писали:
FR>Здравствуйте, Alexéy Sudáchen, Вы писали: AS>>Я имел в виду почему мазохизм остаётся применительно к задачам не связанным с низкоуровневым кодом? FR>Потому что для не низкоуровневых задач есть более высокоуровневый C++ который практически полностью перекрывает FR>все возможности Си.
Это как посмотреть. В каком-то смысле не только перекрывает, но местами даже существенно сужает =)
Здравствуйте, FR, Вы писали:
FR>Скорее 4, твой третий пункт делится на 2: FR>3. С++ с исключениями, классами, STL и шаблонами используемыми только для обобщенного программирования. FR>4. C++ с шаблонами используемыми для метапрограммирования. FR>а с выходом нового стандарта и все пять
Сколько однако возможностей в одном языке С++! И нифига это не серьёзное ограничение что его сложность (библиотеки то на С++ писаны, и часто весьма зубодробильном) делает практически нереальным поиск программеров способных с такой сложностью справиться. =)
Здравствуйте, Alexéy Sudáchen, Вы писали:
FR>>Потому что для не низкоуровневых задач есть более высокоуровневый C++ который практически полностью перекрывает FR>>все возможности Си.
AS>Это как посмотреть. В каком-то смысле не только перекрывает, но местами даже существенно сужает =)
Что-то не могу представить чтобы сужало, все-таки си почти подмножество С++.
Здравствуйте, FR, Вы писали:
FR>>>все возможности Си. AS>>Это как посмотреть. В каком-то смысле не только перекрывает, но местами даже существенно сужает =) FR>Что-то не могу представить чтобы сужало, все-таки си почти подмножество С++.
Ну нифига не подмножество =) А сужает не возможности кодирования, но возможность сдерживать сей процесс в разумных границах сложности. Ну и про кадры я уже написал.
Язык же не сам по себе существует, а для того чтобы решать некую задачу. Решение задачи на С++ имеет тенденцию к трате времени на бессмысленную борьбу с языком.
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>Сколько однако возможностей в одном языке С++! И нифига это не серьёзное ограничение что его сложность (библиотеки то на С++ писаны, и часто весьма зубодробильном) делает практически нереальным поиск программеров способных с такой сложностью справиться. =)
C++ реально переусложнен, те же, и даже большие возможности вполне доступны и на гораздо более простом языке, например D практически полностью может все то что и новый C++0x плюс много
чего дополнительно (GC, иммутабельность, чистые функции и CTFE, замыкания, более мощные шаблоны) но писать на нем проще
чем на C++, неожиданностей гораздо меньше и в этом он как раз ближе к Си.
Здравствуйте, FR, Вы писали:
FR>D практически полностью может все то что и новый C++0x плюс много
Да неплохой язык. От только для моих задач не подходит. У меня только три варианта С, С++ и написать что-то своё =) Последний пока отпадает.
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>Это не задача. Это элемент реализации. Как бы программы пишутся таки для какой-то более нужной цели чем мутексы лочить. Или вы хотите сказать что если нужно синхронизировать пру потоков, то самое лучшее решение залезть в JVM?! ИМХО, конечно, но подход весьма специфический.
Ага, конечно. Вон, чего мелочиться, циклы тоже не задача, а элемент реализации, берешь asm с jmp и вперед! Как бы программы пишутся для какой-то более нужной цели, чем циклами баловаться. Или вы хотите сказать, что если нужны циклы, то лучшее решение для этого брать Си?! ИМХО, конечно, но подход весьма специфичный.
AS>Таки какие реально задачи, хотя бы в вашей практике, требовали всего того перечисленного богатства высокоуровневых возможностей?!
Я понял, когда в руках молоток, то все вокруг кажется гвоздями.
Computer science is no more about computers than astronomy is about telescopes (c) Edsger Dijkstra
Re[7]: Потому что одинаковый результат требует больших трудо
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>Здравствуйте, Wissenschaftler, Вы писали:
W>>Например? В gcc4 спецэффектов не наблюдал. Пример "запретить прерывания, проверить три-пять условий, вернуть ошибку если хотя бы одно выполнилось, проставить флаг, вернуть STATUS_SUCCESS" вполне себе практический.
AS>С конструкцией
AS>
AS>{
AS> Guard x(guarded);
AS> а тут чего-то делаем
AS>}
AS>
AS>Никогда не сталкивались?!
Сталкивался. И? Какие здесь спецэффекты?
W>>Ну вот как только компилятор начинает говорить мне, что надо, а что нет — начинается мазохизм. В идеале, отличие guarded-программы от не-guraded должно состоять в одной строчке, какбэ говорящей компилятору "сделай этот кусок кода guarded". Если начинаются всякие танцы с бубном а-ля заменяем return на result = x; break;, вставляем goto, добавляем кучу фигурных скобок и т.п. — начинается мазохизм.
AS>Это вопрос в том надо ли вам что-то заменять. Мне нет, у меня практически весь код так написан. AS>А вот обьектная модель С++ и его заморочки с типизацией меня не устраивают. Вы разве совершенно не замечаете множеством сложностей с самим языком, что возникают как только мы начинаем активно использовать языковые возможности для управления ресурсами? В результате мифический 'мазохизм' С перерастает в совершенно реальный 'анонизм' С++. Однако это уже достаточно сложно заметить оставаясь в рамках С++. При том что граблей там до и больше. Только запрятаны они более изысканно =) ИМХО конечно, однако моё.
С++ предоставляет огромный инструментарий, но не заставляет использовать его весь и везде. Под каждую задачу подбирается идеально подходящий вариант. Си же сильно ограничивает инструментарий, ничего не предлагая взамен.
W>>Только если do3() состоит из нескольких строчек, начинаются танцы со скобками. AS>Э... ну если вы и на скобках и функциях экономите =) Могу только пожелать вам удачи.
Я стараюсь делать код наиболее читаемым. Если код — инициализация контроллера DMA, состоящая в линейной проверке и установке ряда флагов, описанных на одной странице PDF по контроллеру, и использующихся только один раз при инициализации — да, я хочу, чтобы в коде это также помещалось на один экран и имело очевидную структуру. Размазывать код по функциям из-за ограничений языка, а не для повышения читаемости и повторного использования, я не вижу смысла. добавление кучи скобок и промежуточных переменных запросто сделает из одного экрана текста два.
AS>Наверное для того чтобы иметь другой язык? Сходство с С++ тут чисто идиоматическое. Даже синтаксически наши варианты как вы сами заметили сильно расходятся.
Зачем иметь другой язык, один в один копирующий функционал уже существующего, известного и поддерживаемого? Почувствовать себя Великим Создателем?
Здравствуйте, Alexéy Sudáchen, Вы писали: AS>Pure C — мазохизм?!
Категорически не согласен.
Во-первых
Скрытый текст
Не может называться мазохизмом то, что приносит деньги.
Во-вторых
Скрытый текст
Все познается в сравнении — у C и так достаточно широкая сфера применения,
а в некоторых областях (например, создание операционных систем, написание
драйверов или программ для всяких контроллеров) у него вообще нет альтернатив.
Поэтому, сравнивая очередные два языка и критикуя один из них за отсутствие,
скажем, исключений или сборки мусора, нужно брать во внимание области применения
данных языков, а не только синтаксис и выразительность. В данном случае сравнение
вообще почти не имеет смысла, потому что многое из средств языка C++ и всякий
"сахар" при написании системных и высокопроизводительных приложений может очень
легко потерять практический смысл.
Вот, например, такая ситуация — разрабатывается системный драйвер (на С++) и
все функции, работающие с ресурсами, оборачиваются в RAII-обертки.
Такой вопрос — а нужно ли (и безопасно ли) это вообще ?
На первый взгляд нужно, потому что это позволило бы закрыть всякие потенциальные
бреши и предотвратить возможные утечки памяти. С другой стороны, что если в коде
возникает фатальное исключение и системе лучше всего сразу выбросить синий экран, чтобы
предотвратить возможную дальнейшую порчу данных, а не выполнять раскрутку стека и
вызов деструкторов ? В общем, неоднозначный вопрос.
В-третьих
Скрытый текст
Мегапроекты, целиком или почти целиком написанные на C.
Наверняка многие здесь видели код таких проектов, прилично и доходчиво оформленный,
без описанных в данном обсуждении ужасов. Что как бы косвенно доказывает,
что писать на Pure C вполне возможно и никакой это не мазохизм.
И хоть бы пикнул! И ещё помнится было дело когда на Guard(cs) не пищал.
W>С++ предоставляет огромный инструментарий, но не заставляет использовать его весь и везде. Под каждую задачу подбирается идеально подходящий вариант. Си же сильно ограничивает инструментарий, ничего не предлагая взамен. W>Зачем иметь другой язык, один в один копирующий функционал уже существующего, известного и поддерживаемого? Почувствовать себя Великим Создателем?
То есть вы предлагаете писать на С++ без бюста и компании ?!?! Ну, готовтесь быть сьеденным реальными адептами С++ =) Линейкой будете своим подчинёным по рукам бить чтобы они не использовали 'его весь и везде'? =))
Другой — в смысле не С++. С с соответствующей объвязкой вполне такой язык. И с чего вы решили про копирование функционала?! Какие-то прямо очень далеко идущие выводы у вас. Это как следствие уверенности что вы идеально знаете С++? =) Я вот не знаю его на столько чтобы быть уверенным в каждом своём шаге по этому минному полю.
Однако, как из не использования С++ следует мазохизм в использовании С?!
Здравствуйте, Alexéy Sudáchen, Вы писали:
___>>Потому что, как бы это ни банально звучало, высокоуровневые задачи лучше решать с помощью соответствующих инструментов.
AS>Дык, а что вы понимаете под высокоуровнивостью?! Чего такого нет в С что должно быть в таком инструменте?
Удобных инструментов для работы со сложными структурами данных. Впрочем, в C++ их тоже нет.
Re[9]: Потому что одинаковый результат требует больших трудо
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>Здравствуйте, Wissenschaftler, Вы писали:
AS>>>Никогда не сталкивались?! W>>Сталкивался. И? Какие здесь спецэффекты?
AS>Ну как бы это -
AS>
AS>И хоть бы пикнул! И ещё помнится было дело когда на Guard(cs) не пищал.
И? Вы часто реально писали Guard a(CriticalSection) вместо Guard a(m_CriticalSectionThatProtectsUsageCounter)? Спутать легко то, что похоже по синтаксису, названию, или сценарию использования. Здесь же совершенно разные вещи.
AS>То есть вы предлагаете писать на С++ без бюста и компании ?!?! Ну, готовтесь быть сьеденным реальными адептами С++ =) Линейкой будете своим подчинёным по рукам бить чтобы они не использовали 'его весь и везде'? =))
Я тупо предлагаю засунуть догмы типа "ни строчки на С++", или наоборот "ни класса без template<> и throw()", а разумно выбирать инструментарий, оптимально подходящий для каждой задачи. Если команда — идиоты, и увидев поддержку С++ резко примутся использовать vector<string> vec(3) на каком-нибудь AVR вместо трех указателей внутрь одного буфера, там, где это надо, то тут дело в команде, а не в языке. И вместо битья линейкой по пальцам после большого краха, я четко сформулирую требования по производительности и размеру, которым должен удовлетворять код. Не выполнят требования — проект не будет принят — "команда" обломится с гонораром. Как-то так.
AS>Другой — в смысле не С++. С с соответствующей объвязкой вполне такой язык. И с чего вы решили про копирование функционала?! Какие-то прямо очень далеко идущие выводы у вас. Это как следствие уверенности что вы идеально знаете С++? =) Я вот не знаю его на столько чтобы быть уверенным в каждом своём шаге по этому минному полю.
Знаю настолько, что успешно разработал и сдал заказчикам ряд проектов на нем, в т.ч. на AVR и под kernel-mode. Примерно представляю, насколько больше потратил бы времени, если бы ограничил себя "чистым Си". С другой стороны, считаю многие фичи (например, исключения) неприемлемыми в embedded из-за производительности, памяти и читабельности. Откуда выводы про копирование функционала? Очень просто: разработчики С++ поставили цель: сделать возможность вызова некоторой функции деинициализации при выходе за пределы scope. Сделали это, реализовав деструкторы. Вы сделали то же самое с рядом ограничений, через громоздкий #define на switch() и while(). Копирование функционала в чистом виде.
AS>Однако, как из не использования С++ следует мазохизм в использовании С?!
Из не использования С++ в тех задачах, для упрощения которых он разработан. Условно говоря, Hello World на Turbo Basic (? "Hello, World") намного компактней, чем Hello World на C++. И использовать C++ для решения задачи "написать Hello World" — мазохизм. Для других задач, упрощаемых использованием объектно-ориентированной модели, С++ более удобен, чем Си за счет встроенной поддержки этой модели без костылей.
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>Ну, я уверен что С ты знаешь и выделенное пропустил намеренно, как и -Wall -Werror.
-Wall -Werror — они того, за пределами языка.
В самом Си никаких -Wall -Werror нету, так что программа с точки зрения языка Си замечательно собирается и запускается и делает лажу, если не заюзать компиляторно-зависимые хаки типа -Wall -Werror. В то время как в С++ в самом языке зашита ошибка компиляции при нарушении типизации.
Так что апелляцию к -Wall -Werror — в топку.
А то можно с тем же успехом вспомнить -Wall -Werror (ну и еще -Wextra заодно) и для С++. И -Weff до кучи, чтоб на соответствие майерсовской "Effective C++" проверял
С-программер (Олег К.) и С++ программер (Vain) солидарно считают что программирование на С — мазохизм.
C и С++ — это близнецы браться. Присать на обоих что-то высокоуровневое — это безусловный мазахизм. С++ не более чем море брэкджека и шлюх к низкоуровневому ассемблеру.
Удел обоих языков: числодробилки, дравйверы для стремительно устаревающих ОС, коммерческие проекты где стоимость разработки столь мала по сравнению с нормой прибыли, что даже ради 20% производительности можно жертвовать временем и ресурсами.
Так что выбор между ними это выбор между простым, компактным, переносимым, но более опасным, менее выразительными и между более выразительным, но запутанным, переусложненным и несовместимым межу собой.
Прогресс не стоит на месте. И задач для С++ и С становится все меньше. И тут, как не странно шансы С становятся даже выше, так как самыми ценными качествами языка становятся указатели и манипуляция битами.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>>С некоторыми оговорками я с ними в общем-то согласен, но тем не менее существует стереотип что С — безусловный мазохизм! Вопрос в том почему имено вы так считаете, или не считаете?
Pzz>Я, например, считаю, что программирование на C++ — мазохизм. В отличии от программирования на Си
Здравствуйте, Wissenschaftler, Вы писали:
W>Я стараюсь делать код наиболее читаемым. Если код — инициализация контроллера DMA, состоящая в линейной проверке и установке ряда флагов, описанных на одной странице PDF по контроллеру, и использующихся только один раз при инициализации — да, я хочу, чтобы в коде это также помещалось на один экран и имело очевидную структуру. Размазывать код по функциям из-за ограничений языка, а не для повышения читаемости и повторного использования, я не вижу смысла. добавление кучи скобок и промежуточных переменных запросто сделает из одного экрана текста два.
A propos.
Берем некий файл на C# или Java и начинаем его изучать
Класс такой-то
Поля такие-то
Конструкторы.
Геттеры и сеттеры или функции, возвращающие поле.
В общем, строк так 100 — 200, а то и более
Начинаешь искать — а что же тут делается-то ?
А ничего!
В С это просто структура с тем же числом полей, а в С++ еще с конструкторами и деструктором, может быть. И занимает это все N+2 строчек, где N — число полей.
Вот один интересный момент, связанный с возможностью С++ оптимизировать layout классов, которая отсутствует в С. Как известно, в С тоже можно делать что-то подобное наследованию. Для этого одна структура помещается внутрь другой:
/* C */struct Base { int base_data; };
struct Derived { struct Base base; int derived_data; };
Но С++ за счет прямой поддержки инкапсуляции способен расположить данные класса в памяти более эффективно, чем С структуры, что показывает следующий пример (компилировать С и С++ копиляторами):
#include <stdio.h>
#ifdef __cplusplus
// sizeof(A) == 8class A
{
int n;
char c;
};
// sizeof(B) == 8class B : A
{
char d;
};
#else/* sizeof(A) == 8 */typedef struct
{
int n;
char c;
} A;
/* sizeof(B) == 12 */typedef struct
{
A a;
char d;
} B;
#endif
int main()
{
printf("sizeof(A) == %ld, sizeof(B) == %ld\n", sizeof(A), sizeof(B));
return 0;
}
/*
* C++ output:
* sizeof(A) == 8, sizeof(B) == 8
*
* C output:
* sizeof(A) == 8, sizeof(B) == 12
*/
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>Дело в том что мои программы на С вполне себе используют ООП, хотя и не такой как в С++ и даже не такой как в книжках.
С-программер (Олег К.) и С++ программер (Vain) солидарно считают что программирование на С — мазохизм.
AS>С некоторыми оговорками я с ними в общем-то согласен, но тем не менее существует стереотип что С — безусловный мазохизм! Вопрос в том почему имено вы так считаете, или не считаете? AS>В философию, поскольку вопрос философский =)))
Думаю, написание программ на "чистом С" требует более высокой культуры программирования и пользования. Соответственно, люди с отсутствием таковой возмущены. Вот такая гипотеза.
Re[9]: Потому что одинаковый результат требует больших трудо
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>С некоторыми оговорками я с ними в общем-то согласен, но тем не менее существует стереотип что С — безусловный мазохизм! Вопрос в том почему имено вы так считаете, или не считаете?
Мазохизм. Из-за того, что каждое действие превращается в простыни кода. И нет простейших инструментов типа деструкторов, так что приходится их эмулировать с помощью error_exit'ов.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, Alexéy Sudáchen, Вы писали:
PD>Оверхед от С с классами по сравнению с чистым С — полный нуль. В С++ есть малюсенький оверхед, связанный с виртуальными вызовами через vtable, а здесь и его нет.
Много раз встречал подобные утверждения и всегда было интересно, какой может быть оверхед от виртуальных вызовов?
Re[10]: Потому что одинаковый результат требует больших труд
Здравствуйте, k.o., Вы писали:
KO>Много раз встречал подобные утверждения и всегда было интересно, какой может быть оверхед от виртуальных вызовов?
class Base {
virtual void f() {}
void g() {}
};
class Derived : Base
{
virtual void f() {}
void g() {}
};
Base* pb = new Derived;
pb->g();
pb->f();
Функция g невиртуальная, а поэтому вызывается всегда по типу указателя, так что компилятор строит команду
call g
Функция f виртуальная, а значит вызов идет по типу объекта, на который показывает pd. А какой там объект ? У меня Derived, а мог бы быть Base или NextDerived и т.д. Компилятор не можжет построить прямой вызов.
У каждого класса, в котором есть хоть одна виртуальная функция, есть vtable (название VC, это не стандарт). В ней хранится вот что
возможно, некие поля, не имеющие прямого отношения к вопросу
адрес первой вирт. функции
адрес второй вирт. функции
и т.д.
Каждый экземпляр класса хранит внутри себя указатель на vtable.
Поэтому вызов выглядит примерно так
mov eax,[vtable.function_address]
call [eax]
То есть вместо прямого вызова call = косвенный, с предварительной загрузкой адреса из vtable
Вот и все.
With best regards
Pavel Dvorkin
Re[11]: Потому что одинаковый результат требует больших труд
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>C: PD>>
PD>>struct Point3D
PD>>{
PD>> int x_,y_,z_;
PD>>};
PD>>
C>А где иммутабельность? И функция hashCode? Операторы сравнения (тут покатит memcmp, но стоит добавить одну строчку и усё)?
А я о них говорил ? См. мой исходный постинг. Там речь шла только о том, что масса строк без всякой функциональности. А это все же функциональность, от языка не зависит (не знаю, как в Scala, но в C#-Java придется писать, как и в С/C++)
И, кстати, еще большой вопрос — нужна мне эта hashCode или нет ? И сравнения тоже. Понадобится — тогда и напишу.
With best regards
Pavel Dvorkin
Re[13]: Потому что одинаковый результат требует больших труд
Здравствуйте, Pavel Dvorkin, Вы писали:
C>>А где иммутабельность? И функция hashCode? Операторы сравнения (тут покатит memcmp, но стоит добавить одну строчку и усё)? PD>А я о них говорил ? См. мой исходный постинг. Там речь шла только о том, что масса строк без всякой функциональности. А это все же функциональность, от языка не зависит (не знаю, как в Scala, но в C#-Java придется писать, как и в С/C++)
Такие строки, на самом деле, не особо отвлекают. В отличие от кучи строк внутри тел методов.
PD>И, кстати, еще большой вопрос — нужна мне эта hashCode или нет ? И сравнения тоже. Понадобится — тогда и напишу.
Сравнения и hashCode нужны вообще почти всегда, если объекты кладутся в коллекции.
Sapienti sat!
Re[14]: Потому что одинаковый результат требует больших труд
Здравствуйте, Cyberax, Вы писали:
C>Такие строки, на самом деле, не особо отвлекают.
Такие строки отвлекают порядком. Я целый файл должен просмотреть, чтобы узнать, что там. А там геттеры и сеттеры, геттеры и сеттеры...
С>В отличие от кучи строк внутри тел методов.
А когда в теле методов вызываются другие методы, а те в свою очередь другие — это лучше ? Так хоть все рядом, посмотрел — и все ясно. А в противном случае только и ходишь по файлам и имеешь через полчаса кашу в голове насчет имен классов, методов и т.п.
PD>>И, кстати, еще большой вопрос — нужна мне эта hashCode или нет ? И сравнения тоже. Понадобится — тогда и напишу. C>Сравнения и hashCode нужны вообще почти всегда, если объекты кладутся в коллекции.
Смотря в какие и зачем .
With best regards
Pavel Dvorkin
Re[9]: Потому что одинаковый результат требует больших трудо
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>В С это просто структура с тем же числом полей, а в С++ еще с конструкторами и деструктором, может быть. И занимает это все N+2 строчек, где N — число полей.
Я обычно пишу геттеры/сеттеры даже на чистом Си. Это, во-первых, позволяет очертить публичный интерфейс, потому что как правило не все поля в структуре предназначены для того, чтобы их все подряд трогали. А во-вторых, позволяет позже, не трогая прочего кода, добавить, скажем, вычисление полей on demand, или привязать какое-нибудь действие к изменению какого-нибудь поля и т.п.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, k.o., Вы писали:
KO>>Много раз встречал подобные утверждения и всегда было интересно, какой может быть оверхед от виртуальных вызовов?
PD>Функция g невиртуальная, а поэтому вызывается всегда по типу указателя, так что компилятор строит команду
Вопрос скорее в том, как избежать "оверхеда" при вызове pb->f(), если нужно, чтобы выполнился метод класса Derived? Разумеется, использование полиморфизма времени выполнения там где это не нужно, даст оверхед, но это совершенно неинтересный случай. Интереснее, насколько уместно говрить об оверхеде некоторого подхода, если более быстрого решения всё-равно нет.
Здравствуйте, Cyberax, Вы писали:
C>Мазохизм. Из-за того, что каждое действие превращается в простыни кода. И нет простейших инструментов типа деструкторов, так что приходится их эмулировать с помощью error_exit'ов.
Обычно C++'ный код занимает заметно больше строк, чем сишный эквиавалент. Я имею ввиду, качественний C++'ный код, в котором нельзя, например, скопировать структуру со сложным внутренним миром простым присваиванием (т.е., такое действие либо явно запрещено, либо правильно реализовано в соответствующем конструкторе).
Все эти меры безопасности, о которых так любят говорить адепты C++, они же не автоматически даются, а требуют довольно тщательного прописывания правил игры. Что само по себе занимает заметное количество строк и усилий.
Здравствуйте, k.o., Вы писали:
KO>Вопрос скорее в том, как избежать "оверхеда" при вызове pb->f(), если нужно, чтобы выполнился метод класса Derived? Разумеется, использование полиморфизма времени выполнения там где это не нужно, даст оверхед
Другого полиморфизма в С++ нет, нужность или ненужность я не обсуждал, а просто объяснил, как оно там реализовано.
>Интереснее, насколько уместно говрить об оверхеде некоторого подхода, если более быстрого решения всё-равно нет.
Оверхед имеется в виду по сравнению с невиртуальным вызовом (или с чистым С) , больше ничего.
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>Здравствуйте, jazzer, Вы писали:
J>>Странно было бы не соглашаться с очевидным. AS>Ну для меня это совсем не очевидно =)
J>>Потому что практически все, что можно написать на Си, можно написать и на С++, но не наоборот. За исключением некоторых С99-фич, собственно (некоторых — потому что многие фичи уже вошли в новый стандарт и/или поддерживаются компиляторами подпольно уже сейчас, например, restrict, variadic macros etc).
AS>Ну далеко не всё. В С в отличии от С++ void* приводится к любому другому указателю. Это вроде бы незначительное отличие может в корне менять структуру программы. В скобках запутаешся то же самое писать на плюсах.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, k.o., Вы писали:
KO>>Вопрос скорее в том, как избежать "оверхеда" при вызове pb->f(), если нужно, чтобы выполнился метод класса Derived? Разумеется, использование полиморфизма времени выполнения там где это не нужно, даст оверхед
PD>Другого полиморфизма в С++ нет, нужность или ненужность я не обсуждал, а просто объяснил, как оно там реализовано.
Вобще-то там есть и полиморфизм времени компиляции, но это к делу не относится.
>>Интереснее, насколько уместно говрить об оверхеде некоторого подхода, если более быстрого решения всё-равно нет.
PD>Оверхед имеется в виду по сравнению с невиртуальным вызовом (или с чистым С) , больше ничего.
Просто мне кажется, что разный код, решающий разные задачи.
Re[10]: Потому что одинаковый результат требует больших труд
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>В С это просто структура с тем же числом полей, а в С++ еще с конструкторами и деструктором, может быть. И занимает это все N+2 строчек, где N — число полей.
Pzz>Я обычно пишу геттеры/сеттеры даже на чистом Си. Это, во-первых, позволяет очертить публичный интерфейс, потому что как правило не все поля в структуре предназначены для того, чтобы их все подряд трогали. А во-вторых, позволяет позже, не трогая прочего кода, добавить, скажем, вычисление полей on demand, или привязать какое-нибудь действие к изменению какого-нибудь поля и т.п.
Вот-вот. Я о том же. Берем чистый Си и начинаем с упорством и трудолюбием делать нативные для С++ вещи через систему хитровывернутых макросов и naming convention-ов.
Здравствуйте, Wissenschaftler, Вы писали:
Pzz>>Я обычно пишу геттеры/сеттеры даже на чистом Си. Это, во-первых, позволяет очертить публичный интерфейс, потому что как правило не все поля в структуре предназначены для того, чтобы их все подряд трогали. А во-вторых, позволяет позже, не трогая прочего кода, добавить, скажем, вычисление полей on demand, или привязать какое-нибудь действие к изменению какого-нибудь поля и т.п. W>Вот-вот. Я о том же. Берем чистый Си и начинаем с упорством и трудолюбием делать нативные для С++ вещи через систему хитровывернутых макросов и naming convention-ов.
Здравствуйте, alexeiz, Вы писали:
AS>>Дело в том что мои программы на С вполне себе используют ООП, хотя и не такой как в С++ и даже не такой как в книжках.
A>Ну и расскажи, как ты делаешь ООП в С.
Расскажу, почему бы и нет. Только сначало нужно про автоматичекое освобождение ресурсов рассказать.
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>>С некоторыми оговорками я с ними в общем-то согласен, но тем не менее существует стереотип что С — безусловный мазохизм! Вопрос в том почему имено вы так считаете, или не считаете? C>Мазохизм. Из-за того, что каждое действие превращается в простыни кода. И нет простейших инструментов типа деструкторов, так что приходится их эмулировать с помощью error_exit'ов.
Дык, в том то и дело что можно писать без простыней и error_exit'ов =) И даже проще чем на С++. Хотя, кончно вопрос что пишешь. Если математику через перегруженые опрерации, то кода в С однако больше будет.
Re[12]: Потому что одинаковый результат требует больших труд
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, Wissenschaftler, Вы писали:
Pzz>>>Я обычно пишу геттеры/сеттеры даже на чистом Си. Это, во-первых, позволяет очертить публичный интерфейс, потому что как правило не все поля в структуре предназначены для того, чтобы их все подряд трогали. А во-вторых, позволяет позже, не трогая прочего кода, добавить, скажем, вычисление полей on demand, или привязать какое-нибудь действие к изменению какого-нибудь поля и т.п. W>>Вот-вот. Я о том же. Берем чистый Си и начинаем с упорством и трудолюбием делать нативные для С++ вещи через систему хитровывернутых макросов и naming convention-ов.
Pzz>А что, в C++ геттеры делаются автоматически?
Нет, но синтаксис раза в 2 компактней.
Здравствуйте, k.o., Вы писали:
KO>Вобще-то там есть и полиморфизм времени компиляции, но это к делу не относится.
+1
PD>>Оверхед имеется в виду по сравнению с невиртуальным вызовом (или с чистым С) , больше ничего.
KO>Просто мне кажется, что разный код, решающий разные задачи.
Конечно. В сущности вопрос — нужен этот полиморфизм или нет. Если не нужен — то без него можно обойтись (Сейчас набегут здешние специалисты и объяснят, что деструктор должен быть виртуальным . Можно этот полиморфизм смоделировать и на чистом С, но писать придется все самому.
Pzz>Обычно C++'ный код занимает заметно больше строк, чем сишный эквиавалент. Я имею ввиду, качественний C++'ный код, в котором нельзя, например, скопировать структуру со сложным внутренним миром простым присваиванием (т.е., такое действие либо явно запрещено, либо правильно реализовано в соответствующем конструкторе).
Если совсем правильно, то есть никаких голых указателей, все члены или умные указатели или обертки или контейнеры, то кода меньше чем на си
получается. Конструкторы для таких классов тривиальные, копирующие вообще не нужны обычно. Но это не бесплатно, по производительности конечно.
Pzz>Все эти меры безопасности, о которых так любят говорить адепты C++, они же не автоматически даются, а требуют довольно тщательного прописывания правил игры. Что само по себе занимает заметное количество строк и усилий.
При правильном стиле практически автоматом. Эти правила приходится по полной использовать только в самых "низкоуровневых" классах держателях ресурсов и
обертках.
Здравствуйте, Alexéy Sudáchen, Вы писали:
C>>Мазохизм. Из-за того, что каждое действие превращается в простыни кода. И нет простейших инструментов типа деструкторов, так что приходится их эмулировать с помощью error_exit'ов. AS>Дык, в том то и дело что можно писать без простыней и error_exit'ов =) И даже проще чем на С++. Хотя, кончно вопрос что пишешь. Если математику через перегруженые опрерации, то кода в С однако больше будет.
Простой линейный код даже сложно писать в чистом С. Что-то типа ядерного кода без error_exit'ов получается вообще некрасиво.
Здравствуйте, Pzz, Вы писали:
C>>Мазохизм. Из-за того, что каждое действие превращается в простыни кода. И нет простейших инструментов типа деструкторов, так что приходится их эмулировать с помощью error_exit'ов. Pzz>Обычно C++'ный код занимает заметно больше строк, чем сишный эквиавалент.
Не занимает, проверено.
Pzz>Я имею ввиду, качественний C++'ный код, в котором нельзя, например, скопировать структуру со сложным внутренним миром простым присваиванием (т.е., такое действие либо явно запрещено, либо правильно реализовано в соответствующем конструкторе).
Так а в С это превращается в ворохи функций, по типу GTK.
Здравствуйте, Cyberax, Вы писали:
C>Простой линейный код даже сложно писать в чистом С. Что-то типа ядерного кода без error_exit'ов получается вообще некрасиво.
Почему? Делаешь реализацию исключений и авторелиз-пула. И пишешь совершенно спокойно простой и понятный код, так как будто-бы у тебя есть гарбедж коллектор и без всяких goto на обработку ошибок. Неужели так сложно?
Ну напишу я на неделе пост про авторматическое управление ресурсами, а потом, ещё через недельку, про ООП и затем уже как всё это вместе можно пользовать. Написание таких вещей даже в сжатом виде требует времени и сил, а разжовывать каждую деталь — это на книгу наберётся.
Re[14]: Потому что одинаковый результат требует больших труд
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, Wissenschaftler, Вы писали:
Pzz>>>А что, в C++ геттеры делаются автоматически? W>>Нет, но синтаксис раза в 2 компактней.
Pzz>В APL синтаксис еще компактнее, что вряд ли является его достоинством
В APL — не является, т.к. ухучшается читаемость. В С++ является, т.к. читаемость "m_Obj.GetValue()" выше, чем "OBJ_GetVal(OUTER_GetVal(&self))".
Здравствуйте, Alexéy Sudáchen, Вы писали:
C>>Простой линейный код даже сложно писать в чистом С. Что-то типа ядерного кода без error_exit'ов получается вообще некрасиво. AS>Почему? Делаешь реализацию исключений и авторелиз-пула. И пишешь совершенно спокойно простой и понятный код, так как будто-бы у тебя есть гарбедж коллектор и без всяких goto на обработку ошибок. Неужели так сложно?
Сложно. В основном из-за того, что реализация исключений на С нормально невозможна, особенно в присутствие FP. Кроме того, память — это не единственный ресурс.
AS>Ну напишу я на неделе пост про авторматическое управление ресурсами, а потом, ещё через недельку, про ООП и затем уже как всё это вместе можно пользовать. Написание таких вещей даже в сжатом виде требует времени и сил, а разжовывать каждую деталь — это на книгу наберётся.
Можно. Но только всё получится кривое, макросное и в результате воссоздастся половина С++. С глюками.
Sapienti sat!
Re[15]: Потому что одинаковый результат требует больших труд
Здравствуйте, Pavel Dvorkin, Вы писали:
C>>Такие строки, на самом деле, не особо отвлекают. PD>Такие строки отвлекают порядком. Я целый файл должен просмотреть, чтобы узнать, что там. А там геттеры и сеттеры, геттеры и сеттеры...
Ну а зачем его смотреть было весь?
С>>В отличие от кучи строк внутри тел методов. PD>А когда в теле методов вызываются другие методы, а те в свою очередь другие — это лучше ? Так хоть все рядом, посмотрел — и все ясно. А в противном случае только и ходишь по файлам и имеешь через полчаса кашу в голове насчет имен классов, методов и т.п.
Я чего-то не понимаю. А как в случае с С?
Здравствуйте, Cyberax, Вы писали:
C>Сложно. В основном из-за того, что реализация исключений на С нормально невозможна, особенно в присутствие FP. Кроме того, память — это не единственный ресурс.
Что ест FP?
AS>>Ну напишу я на неделе пост про авторматическое управление ресурсами, а потом, ещё через недельку, про ООП и затем уже как всё это вместе можно пользовать. Написание таких вещей даже в сжатом виде требует времени и сил, а разжовывать каждую деталь — это на книгу наберётся. C>Можно. Но только всё получится кривое, макросное и в результате воссоздастся половина С++. С глюками.
А если немного, на минуточку, представить, что можно делать как-то иначе чем в С++?!
Здравствуйте, Alexéy Sudáchen, Вы писали:
C>>Сложно. В основном из-за того, что реализация исключений на С нормально невозможна, особенно в присутствие FP. Кроме того, память — это не единственный ресурс. AS>Что ест FP?
Floating point. Бросок асинхронного исключения может оставить FP в невнятном состоянии.
AS>>>Ну напишу я на неделе пост про авторматическое управление ресурсами, а потом, ещё через недельку, про ООП и затем уже как всё это вместе можно пользовать. Написание таких вещей даже в сжатом виде требует времени и сил, а разжовывать каждую деталь — это на книгу наберётся. C>>Можно. Но только всё получится кривое, макросное и в результате воссоздастся половина С++. С глюками. AS>А если немного, на минуточку, представить, что можно делать как-то иначе чем в С++?!
Можно. GTK вон целую объектную систему на макросах построила, даже с рефлексией. Проблем-то никаких нет.
Но зачем?!?!?
Sapienti sat!
Re[16]: Потому что одинаковый результат требует больших труд
Здравствуйте, Cyberax, Вы писали:
C>>>Такие строки, на самом деле, не особо отвлекают. PD>>Такие строки отвлекают порядком. Я целый файл должен просмотреть, чтобы узнать, что там. А там геттеры и сеттеры, геттеры и сеттеры... C>Ну а зачем его смотреть было весь?
Чтобы понять, что там смотреть не на что. А как иначе я могу в этом убедиться ?
PD>>А когда в теле методов вызываются другие методы, а те в свою очередь другие — это лучше ? Так хоть все рядом, посмотрел — и все ясно. А в противном случае только и ходишь по файлам и имеешь через полчаса кашу в голове насчет имен классов, методов и т.п. C>Я чего-то не понимаю. А как в случае с С?
А на С нет манеры на каждый чих писать функцию. Функция там что-то делает, а не поле возвращает.
С-программер (Олег К.) и С++ программер (Vain) солидарно считают что программирование на С — мазохизм. AS>С некоторыми оговорками я с ними в общем-то согласен, но тем не менее существует стереотип что С — безусловный мазохизм! Вопрос в том почему имено вы так считаете, или не считаете?
В силу требований приходилось писать некоторые куски проекта на pure C.
В сравнении с тем, как бы это было написано на С++, да — мазохизм в чистом виде.
Закат солнца строго вручную.
Куча техник, упрощающих как жизнь так и код просто отсутствует (типа RAII, шаблонных хелперов, контейнеров и прочая и прочая). Не, ну это конечно можно сэмулировать, ценой потери читабельности, отлаживаемости и времени.
Так что в сравнении с С++ писать на pure C просто на порядок менее удобно.
Впрочем если весь проект целиком пишется на С то оно в общем то терпимо. Но делать С вставки в С++ проект крайне неприятно, т.к. практически всё, что в них используется, приходится писать с нуля.
Здравствуйте, Alexey Sudachen, Вы писали:
AS>Относительно утечки ресурсов не всё так просто. В С есть свои техники аналогичные идеоме умных указателей и RAII.
Оно автоматически работает или всё таки для этого надо соблюдать жёстко заданный кодстайл?
AS> К тому же, на доступных версиях компилятора С++ до определённого момента (где-то в середине 90-ых если мне склероз не изменяет)
Если мне память не изменяет сейчас 2011 год. Т.е. уже более 15 лет прошло от середины 90х.
Какой смысл приводить аргумент, который давно уже не валиден?
AS>Но и в С вобщем-то тоже =) Я постараюсь на неделе написать и про это.
Напиши, былоб интересно посмотреть.
Здравствуйте, __lambda__, Вы писали:
AS>>С некоторыми оговорками я с ними в общем-то согласен, но тем не менее существует стереотип что С — безусловный мазохизм! Вопрос в том почему имено вы так считаете, или не считаете? ___>Смотря для каких задач его применять. Для низкоуровневого программирования, Си отличный инструмент.
Помниццо прошивка под смарт карты на С нормально писалась.
Ну да впрочем там кроме С был только asm, а на нём уж очень впадлу было.
___>Ну или для программ близких к железу, а также для написания критичных к скорости участков кода.
Тут уже вотчина как С так и С++. И качество кода определяется скорее бардаком в голове девелопера чем выбором С или С++.
Здравствуйте, Alexey Sudachen, Вы писали:
AS>А сужает не возможности кодирования, но возможность сдерживать сей процесс в разумных границах сложности.
А можно какой нить наглядный пример? Бо что то представить не получается.
Здравствуйте, Alexey Sudachen, Вы писали:
AS>Ну далеко не всё. В С в отличии от С++ void* приводится к любому другому указателю. Это вроде бы незначительное отличие может в корне менять структуру программы.
Ничуть.
Просто ставим explicit приведения где надо.
Всё остальное остаётся как есть, структура не меняется.
AS> В скобках запутаешся то же самое писать на плюсах.
там всего то 1 пара скобок. Грубо говоря: a = (T*)b;
PS. *_cast<> не люблю за многословность. C-style cast достаточно для 99.9% случаев.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: Потому что одинаковый результат требует больших трудо
Здравствуйте, Alexey Sudachen, Вы писали:
AS>То есть вы предлагаете писать на С++ без бюста и компании ?!?! Ну, готовтесь быть сьеденным реальными адептами С++
Присоединяюсь к Wissenschaftler.
Буст — не нужен (С)
Не надо всё подряд без разбору тащить в проект.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: Потому что одинаковый результат требует больших труд
Здравствуйте, Pzz, Вы писали:
Pzz>Я обычно пишу геттеры/сеттеры даже на чистом Си. Это, во-первых, позволяет очертить публичный интерфейс, потому что как правило не все поля в структуре предназначены для того, чтобы их все подряд трогали. А во-вторых, позволяет позже, не трогая прочего кода, добавить, скажем, вычисление полей on demand, или привязать какое-нибудь действие к изменению какого-нибудь поля и т.п.
Здравствуйте, Alexey Sudachen, Вы писали:
AS>делает практически нереальным поиск программеров способных с такой сложностью справиться. =)
Величина, определяющая кол-во интеллекта на планете есть величина постоянная.
А население растёт...
Здравствуйте, okman, Вы писали:
O>Вот, например, такая ситуация — разрабатывается системный драйвер (на С++) и O>все функции, работающие с ресурсами, оборачиваются в RAII-обертки. O>Такой вопрос — а нужно ли (и безопасно ли) это вообще ? O>На первый взгляд нужно, потому что это позволило бы закрыть всякие потенциальные O>бреши и предотвратить возможные утечки памяти. С другой стороны, что если в коде O>возникает фатальное исключение и системе лучше всего сразу выбросить синий экран, чтобы O>предотвратить возможную дальнейшую порчу данных, а не выполнять раскрутку стека и O>вызов деструкторов ? В общем, неоднозначный вопрос.
Однозначный.
Исключение в драйвере это вообще особая тема. Как правило исключение == BSOD и никто и не пытается что то там разматывать.
А RAII там нужны для того, чтоб не было утечки ресурсов по вине программиста. С RAII не получится "забыть" дописать освобождение.
Здравствуйте, CreatorCray, Вы писали:
CC>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>-исключения PD>>-полиморфизм. PD>>-STL CC>+ templates без фанатизма.
А я их не исключал. А вот с фанатизмом — да, стоит исключить
Здравствуйте, Cyberax, Вы писали:
C>Floating point. Бросок асинхронного исключения может оставить FP в невнятном состоянии.
И в чём проблема его нормально сохранить/восстановить?!
AS>>А если немного, на минуточку, представить, что можно делать как-то иначе чем в С++?! C>Можно. GTK вон целую объектную систему на макросах построила, даже с рефлексией. Проблем-то никаких нет. C>Но зачем?!?!?
Э... как бы GObject фактически то же самое что в С++, но вид сбоку. В этом смысле я тоже не очень понимаю зачем =)
CC>PS. *_cast<> не люблю за многословность. C-style cast достаточно для 99.9% случаев.
Значит, ты неправильно понял, зачем эта многословность. Она же неспроста. Это сигнал разработчику: задумайся, а нужно ли тебе вообще преобразование типа здесь? Надо не скрывать проблему, используя C-style, а улучшать архитектуру. Если это пока невозможно, то пусть тут торчит _cast, как заноза.
В некотором смысле жаль, что в C++ так лелеют обратную совместимость. Отказ от многих фич C (начиная с преобразования типов) резко бы улучшил язык. Резко сократив сообщество пользователей, конечно .
Re[11]: Потому что одинаковый результат требует больших труд
Здравствуйте, CreatorCray, Вы писали:
Pzz>>Я обычно пишу геттеры/сеттеры даже на чистом Си. Это, во-первых, позволяет очертить публичный интерфейс, потому что как правило не все поля в структуре предназначены для того, чтобы их все подряд трогали. А во-вторых, позволяет позже, не трогая прочего кода, добавить, скажем, вычисление полей on demand, или привязать какое-нибудь действие к изменению какого-нибудь поля и т.п.
CC>Вот оно, premature pessimization в чистом виде.
Ну нет, конечно. Инлайновые функции ничего не стоят.
С-программер (Олег К.) и С++ программер (Vain) солидарно считают что программирование на С — мазохизм.
Почему ты мне присваиваешь свои слова? Я не говорил что программирование на Си — мазохизм.
За Vain`a говорить не буду, скажу за себя. Мне одинаково нравятся и С и С++. Конкретно в той ветке, тебе сказали сказали что ты пихаешь в программу на Си парадигмы которые так естественны для плюсов но абсолютно неестественны для Си. Эти самые парадигмы идут Сишной программе как корове седло. Поэтому тебе предложили отказаться думать как С++ программист когда пишешь программу на Си. Если ты этого сделать не можешь, то сменить инструмент. Все!
Здравствуйте, Alexéy Sudáchen, Вы писали:
C>>Floating point. Бросок асинхронного исключения может оставить FP в невнятном состоянии. AS>И в чём проблема его нормально сохранить/восстановить?!
В том и проблема.
AS>>>А если немного, на минуточку, представить, что можно делать как-то иначе чем в С++?! C>>Можно. GTK вон целую объектную систему на макросах построила, даже с рефлексией. Проблем-то никаких нет. C>>Но зачем?!?!? AS>Э... как бы GObject фактически то же самое что в С++, но вид сбоку. В этом смысле я тоже не очень понимаю зачем =)
Ну вот и возникает вопрос — нафиг всё было делать, если можно взять С++.
Здравствуйте, Kswapd, Вы писали:
K>Значит, ты неправильно понял, зачем эта многословность. Она же неспроста.
Спасибо, кэп!
K>Надо не скрывать проблему, используя C-style, а улучшать архитектуру. Если это пока невозможно, то пусть тут торчит _cast, как заноза.
Не, всё не так понято.
У меня приведение используется ровно там, где без него просто никак. Просто длинной записи *_cast<TYPE> я предпочитаю короткую (TYPE).
Ну а dynamic_cast вообще за всё время ни разу не понадобился.
K>В некотором смысле жаль, что в C++ так лелеют обратную совместимость.
Это кому как.
K>Отказ от многих фич C (начиная с преобразования типов) резко бы улучшил язык. Резко сократив сообщество пользователей, конечно .
Улучшил ли?
ИМХО получился бы ещё один язык непонятного назначения, интересный лишь группе фанатов.
Здравствуйте, Cyberax, Вы писали:
C>>>Floating point. Бросок асинхронного исключения может оставить FP в невнятном состоянии. AS>>И в чём проблема его нормально сохранить/восстановить?! C>В том и проблема.
Ну дык раскрой проблемность сего действия, для меня она как-то не очевидна.
AS>>Э... как бы GObject фактически то же самое что в С++, но вид сбоку. В этом смысле я тоже не очень понимаю зачем =) C>Ну вот и возникает вопрос — нафиг всё было делать, если можно взять С++.
Ну, спроси об этом авторов GTK+ меня то чего спрашивать? Я этого не знаю.
Здравствуйте, Олег К., Вы писали:
ОК>За Vain`a говорить не буду, скажу за себя. Мне одинаково нравятся и С и С++. Конкретно в той ветке, тебе сказали сказали что ты пихаешь в программу на Си парадигмы которые так естественны для плюсов но абсолютно неестественны для Си.
Гы, обажаю людей которые хорошо знаю чёрное, и уверены что белое тоже. А вот между этим если что и замечают, то только отенки серого. Их так забавно троллить =)
ОК>Эти самые парадигмы идут Сишной программе как корове седло. Поэтому тебе предложили отказаться думать как С++ программист когда пишешь программу на Си. Если ты этого сделать не можешь, то сменить инструмент. Все!
Ты знаешь какие-нить ещё фразы кроме 'вон из нашего двора'? Я не собираюсь отказваться думать, и делать как все, просто по тому что так все делают — тоже не собираюсь. Благо имею достаточно мозгов и воли чтобы себе это позволить. Так что спасибо, но я буду делать так как считаю нужным.
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>Относительно утечки ресурсов не всё так просто. В С есть свои техники аналогичные идеоме умных указателей и RAII. К тому же, на доступных версиях компилятора С++ до определённого момента (где-то в середине 90-ых если мне склероз не изменяет) было крайне тяжело контролировать ресурсы.
Склероз тебе изменяет. Исключения в С++ появились практически сразу, так же как и техника RAII. Собсно, из-за этой техники отсутствует ключевое слово finally.
AS>Но и в С вобщем-то тоже =)
Можно пример в пару строк, как это автоматизировать на С?
AS>Является ли минусом слабая типизация — это вообще сложный вопрос. Именно для С — это гигантский плюс, ИМХО =)
Э, нет. С++ предоставляет все ср-ва для нарушения типобезоасности. Так что, если очень надо стукнуть молотком по пальцам — ради бога. Тебя раздражает, что эти намерения нужно выражать явно? Это как в "дружелюбной" программе: "вы точно хотите стукнуть себе молотком по пальцам?" [Да] [Нет] [Не знаю С++]
Здравствуйте, vdimas, Вы писали:
V>Склероз тебе изменяет. Исключения в С++ появились практически сразу, так же как и техника RAII. Собсно, из-за этой техники отсутствует ключевое слово finally.
Да шо вы говорите! Я вообще-то пишу на плюсах ещё с тех времён когда в них не было ни исключений ни шаблонов =)))) Давай расскажи мне за RAII без шаблонов =)
AS>>Но и в С вобщем-то тоже =) V>Можно пример в пару строк, как это автоматизировать на С?
Управление ресурсами? Ну напишу как время будет. Если хочшь пару строк, пожалуйста —
int buildno;
__Auto_Unwind
buildno = strtol(Str_Trim(Oj_Read_Line(File_Open("textfile","r")),0,10);
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Отмечу и один недостаток. Деструктор. В С закрывающая фигурная скобка у меня абсолютно никаких эмоций не вызывает, код ей не соответствует. В С++ на закрывающую фигурную может оказаться повещенным такое количество действий, что мало не покажется. Иными словами, в С для выполнения чего бы то ни было надо именно в этом месте написать код, а в С++ он вызовется, хотя именно в этой строке ничего не написано.
Недавно пришла в голову идея специально для тех, кто волнуется, что при выходе из scope-а в С++ производятся какие-то дополнительные действия.
#define CALL_DESTRUCTOR(X) __noop /* define for your compiler appropriately */void foo()
{
MyClass a;
MyClass b;
// ...
CALL_DESTRUCTOR(b); // must be in reverse order!
CALL_DESTRUCTOR(a);
}
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Конечно. В сущности вопрос — нужен этот полиморфизм или нет. Если не нужен — то без него можно обойтись (Сейчас набегут здешние специалисты и объяснят, что деструктор должен быть виртуальным . Можно этот полиморфизм смоделировать и на чистом С, но писать придется все самому.
И в качестве побочного эффекта при ручной реализации компилятор не сможет проводить спекулятивную оптимизацию.
А она может дать весьма существенную экономию по сравнению с гарантированно виртуальным вызовом.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Конечно. В сущности вопрос — нужен этот полиморфизм или нет. Если не нужен — то без него можно обойтись (Сейчас набегут здешние специалисты и объяснят, что деструктор должен быть виртуальным . Можно этот полиморфизм смоделировать и на чистом С, но писать придется все самому. S>И в качестве побочного эффекта при ручной реализации компилятор не сможет проводить спекулятивную оптимизацию. S>А она может дать весьма существенную экономию по сравнению с гарантированно виртуальным вызовом.
Я же не предлагаю так делать на С++
Ну а если на С все же эмулировать (конечно, вопрос — зачем ?), то придется.
Здравствуйте, FR, Вы писали:
FR>Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>>Сколько однако возможностей в одном языке С++! И нифига это не серьёзное ограничение что его сложность (библиотеки то на С++ писаны, и часто весьма зубодробильном) делает практически нереальным поиск программеров способных с такой сложностью справиться. =)
FR>C++ реально переусложнен, те же, и даже большие возможности вполне доступны и на гораздо более простом языке, например FR>D практически полностью может все то что и новый C++0x плюс много FR>чего дополнительно (GC, иммутабельность, чистые функции и CTFE, замыкания, более мощные шаблоны) но писать на нем проще FR>чем на C++, неожиданностей гораздо меньше и в этом он как раз ближе к Си.
Вы лучше скажите когда выйдет стабильный компилятор для D ?
А еще я хочу с бекэндом GCC или LLVM, а еще лучше бекэнд VC
И еще нормальные средства отладки, а еще лучше интеграция с VisualStudio.
Ну можно и не студия, но на том же уровне как с С++.
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>Да шо вы говорите! Я вообще-то пишу на плюсах ещё с тех времён когда в них не было ни исключений ни шаблонов =)))) Давай расскажи мне за RAII без шаблонов =)
При чем тут шаблоны и RAII? И в каких это годах в C++ не было исключений? Это до начала 90-х разве что. Уже в 91-м исключения были.
AS>
Здравствуйте, vdimas, Вы писали:
AS>>Да шо вы говорите! Я вообще-то пишу на плюсах ещё с тех времён когда в них не было ни исключений ни шаблонов =)))) Давай расскажи мне за RAII без шаблонов =) V>При чем тут шаблоны и RAII? И в каких это годах в C++ не было исключений? Это до начала 90-х разве что. Уже в 91-м исключения были.
Да шо вы говорите?! =))) В 92-ом я писал на Borland C++ 2.0, в 94-ом на тройке. Может у вас был какой-то другой компилер? И хде вы его интересно взяли?! Шаблоны же тут при том что писать на каждый чих обёртки управляющие ресурсами не сильно удобнее чем управлять руками.
AS>>
Я так понииаю это работает только с DMD...
А что делать с GDC и LDC2 ?
__>>Всего этого нет, а значит: Не нужен
FR>Все есть, а про Немерле в другой ветке
Да вроде здесь тоже про него можно
Gdc когда я смотрел, еще для версии 1.x работал весьма стабильно, оптимизировал код гораздо лучше
чем dmd. Были только мелкие проблемы с линовкой некоторых библиотек.
Ldc и dnet практически не щупал.
FR>>http://www.dsource.org/projects/descent
__>Я так понииаю это работает только с DMD... __>А что делать с GDC и LDC2 ?
Я сейчас только visuald изредка использую, descent смотрел когда он еще весьма сырой был.
Но ссылка с главной странички descent говорит что с ldc он вполне дружит.
Здравствуйте, Alexéy Sudáchen, Вы писали:
AS>[Pure C] почему мазохизм?!
Если плёткой бить себя по телу, то конечно это мазохизм. А от если бить ей коня, на котором ты сидишь, то никакой боли и только радость от быстрого путешествия с ветерком.
Разумеется, в современном автомобиле или поезде путешествовать теплее и комфортнее, да и быстрее достигаешь нужного пункта назначения, нежели на спине лошади, однако в первом случае ты можешь путешествовать только по дорогам и прочим рельсам, которые заботливо проложили для тебя строители, а на лошади тебе подвластны как дороги, так и бездорожье, в том числе всякие дикие леса, где ни одного авто не пролезет. Катание верхом закаляет всадника физически и развивает духовно, бездушное авто заставляет деградировать. Плюс лошадка это ностальгия по тем временам, когда они использовались обширно, дань памяти предков, если хотите
Здравствуйте, D.Lans, Вы писали:
DL>а на лошади тебе подвластны как дороги, так и бездорожье, в том числе всякие дикие леса, где ни одного авто не пролезет
Ну-ну, верхом на лошади без тропы по лесу далеко не уедешь, а по дикому и пешком-то трудно будет