Здравствуйте, _NN_, Вы писали:
V>>но clang ошибку показал: _NN>Тут предупреждение, а не ошибка компиляции.
Но результат то неверный, — значит ошибка в этом месте
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
S>>И да, без ответного примера можете ответ не писать. Пожалейте и мое и свое время, перестаньте демонстрировать свои жалкие потуги на убогий троллинг.so V>Здесь тебе не ЛОР, с хамством завязывай
Очевидно, что не LOR, на LOR-е оппонента, который упорно отказывается аргументировать свое мнение, давно бы выгнали из темы ссаными тряпками. Здесь, вроде бы, так делать не принято, приходится с троллем расшаркиваться с сохранением внешних приличий. Поэтому я просто подожду, пока вы:
a) перестанете отмахиваться от приведенных вам аргументов (отсутствие RAII в C, например, или проблемы с переносимостью C-шного кода в случае использования GNU-тых расширений языка);
b) таки приведете примеры реальных проблем с enable_if, с которыми может столкнуться обычный C++ разработчик (а не контрибьюторы STL, Boost, Folly, Eigen и др. хардкорных библиотек).
Здравствуйте, so5team, Вы писали:
S>Очевидно, что не LOR, на LOR-е оппонента, который упорно отказывается аргументировать свое мнение, давно бы выгнали из темы ссаными тряпками. Здесь, вроде бы, так делать не принято, приходится с троллем расшаркиваться с сохранением внешних приличий. Поэтому я просто подожду, пока вы:
Это ещё большой вопрос кто сюда пришёл троллить.
S>a) перестанете отмахиваться от приведенных вам аргументов (отсутствие RAII в C, например, или проблемы с переносимостью C-шного кода в случае использования GNU-тых расширений языка);
никто и не отмахивается, перестаньте придумывать себе утверждения оппонента
S>b) таки приведете примеры реальных проблем с enable_if, с которыми может столкнуться обычный C++ разработчик (а не контрибьюторы STL, Boost, Folly, Eigen и др. хардкорных библиотек).
Я уже привел один пример со сложностью в понимании. Дальше разжёвывать не собираюсь.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, so5team, Вы писали:
S>b) таки приведете примеры реальных проблем с enable_if, с которыми может столкнуться обычный C++ разработчик (а не контрибьюторы STL, Boost, Folly, Eigen и др. хардкорных библиотек).
"обычный C++ разработчик" не знает об enable_if от слова совсем. И слава богу. Т.к. шаблоны дальше библиотек общего назначения вылазить не должны.
Давайте я перечислю чем С лучше C++.
— на порядок легче изучить
— на порядок проще анализировать ( как тулзами так и человеком )
— на порядок меньше результирующий бинарный код
— на порядок меньше аллокаций в куче ( из за общего подхода к разработке и интрузивных контейнеров )
— стабильный ABI
— элементарный байндинг к другим языкам
— абсолютно предсказуемый execution flow (из-за отсутствия исключений)
— унифицированный стиль разработки. Две программы на С гораздо более похожи по стилю, конвенциям и вообще подходу, нежели две программы на C++
— практически все разработчики на C знают язык хорошо. "Разработчик C++" это очень размытое понятие, там где один использует "С с классами" второй вовсю использует шаблонную магию. Там где один использует new, другой использует vector. Там где один использует исключения, другой не использует. Итд.
С не хуже С++, и не лучше. Это другой инструмент. Это скальпель. Вы им не нарубите лес, но сможете провести ювелирную операцию.
Здравствуйте, antropolog, Вы писали:
A>Давайте я перечислю чем С лучше C++.
Это список не того, чем лучше, а того, чем отличаются. В зависимости от задачи, которую требуется решать, это может быть список как достоинств, так и недостатков.
А с учетом того, что успешные разработки, как правило, имеют тенденцию разрастаться в размерах и сложности, то скорее недостатков.
Здравствуйте, so5team, Вы писали:
S>Это список не того, чем лучше, а того, чем отличаются. В зависимости от задачи, которую требуется решать, это может быть список как достоинств, так и недостатков.
нет, это именно что достоинства. Недостатки могут быть комплементарны этим достоинтсвам, но никак не отменять их.
Здравствуйте, antropolog, Вы писали:
S>>Это список не того, чем лучше, а того, чем отличаются. В зависимости от задачи, которую требуется решать, это может быть список как достоинств, так и недостатков.
A>нет, это именно что достоинства. Недостатки могут быть комплементарны этим достоинтсвам, но никак не отменять их.
Из достоинств, которые там вряд ли поддаются сомнению только простота языка и стабильность ABI. Все остальное можно развернуть в какую угодно сторону.
Впрочем, как и простоту, т.к. в нонешние времена простота С синоним убогости.
Здравствуйте, so5team, Вы писали:
S>А теперь представим, что пулы и арены в нашей предметной области не шибко применимы и нам таки нужны объекты со своими деструкторами, которые нужно таки вызвать. Например, это какое-то содержимое окошка с rich-text-ом или векторным-изображением и нам нужно чистить за собой GUI-объекты (шрифты, кисти, карандаши и т.д.). В C++ мы все это имеем из коробки в виде деструкторов. Что в C?
Я ведь не утверждаю, прошу заметить, что деструкторы не нужны. В C++ есть заметное количество полезных и удобных штук. Я утверждаю, что там их слишком много, и в целом язык сложный, вычурный и несбалансированный. В результате цена, которую приходится платить за сложность языка становится сравнима с той выгодой, которую приносит его использование.
По мне, так проще конструктор/деструктор руками позвать, чем тратить мозговое вещество на то, чтобы следить за всеми этими прибамбасами C++.
Pzz>>Зачем он вам сдался, этот хитрый контейнер?
S>Ну вот Boost.MultiIndex отличный пример такого контейнера. Или я захочу сделать реализацию std::map-а на базе BTree, а не на базе rb-tree.
rb-tree-то (сам алгоритм) все равно придется руками писать, а это в C++ ничем не проще. А если вам захочется написать его в темплейтно-обобщенном виде, так еще и сложнее.
S>Да, но в C++ я напишу его один раз под целое семейство типов. А в Си это будет либо трах с макросами, либо копипаста. И то, и другое сложно назвать более лучшим вариантом.
А он вам нужен, конкретно в вашей прикладной задаче, на целое семейство типов?
Вообще, стандартные контейнеры неплохо справляются с большинством задач. Если хочется нестандартного контейнера, скорее всего это связано с тем, что специфика прикладной задачи плохо укладывается в стандартный контейнер. Скажем, хочется очень быстрого поиска с приподвывертом, а стандартные контейнеры обеспечивают среднюю скорость поиска, но зато без приподвыверта.
Но если у вас потребность в нестандартном контейнере исходит из прикладной задачи, вряд ли вам понадобится хранить в этом контейнее целое семейство типов. Поэтому ваш пример с теоретической точки зрения хорош, но к практике вряд ли имеет отношение.
Здравствуйте, Pzz, Вы писали:
Pzz>В C++ есть заметное количество полезных и удобных штук. Я утверждаю, что там их слишком много, и в целом язык сложный, вычурный и несбалансированный. В результате цена, которую приходится платить за сложность языка становится сравнима с той выгодой, которую приносит его использование.
И опять все будет голословно, не так ли?
Я вот что скажу: в C++ вы можете ограничить себя тем подмножеством, которого вам достаточно и с которым вы не испытываете проблем. А когда этого оказывается недостаточно, то выйти за рамки. Или расширить для себя эти рамки.
А вот в C быстро достигается потолок. И все нужно делать ручками. Тратя свое мозговое вещество на то, что в C++ за вас бы делал компилятор. И не вылавливая потом баги, которые были допущены по недосмотру. Или потому, что уже никто не помнит, какие правила владения и очистки ресурсов были заложены в проекте когда-то давным-давно.
Pzz>rb-tree-то (сам алгоритм) все равно придется руками писать, а это в C++ ничем не проще.
Проще.
Pzz>А он вам нужен, конкретно в вашей прикладной задаче, на целое семейство типов?
Знаете, я когда-то давно был удивлен, зачем класс complex был сделан шаблоном. Да еще таким, который мог принимать char-ы. До тех пор, пока не столкнулся с задачей, в которой как раз потребовалось иметь complex<char>.
Так что возможность взять и со временем заменить btree<int> на btree<short> или на btree<long long> очень дорого стоит. А если туда еще можно запихнуть любой собственный тип, то вообще здорово.
Pzz>но к практике вряд ли имеет отношение.
Здравствуйте, so5team, Вы писали:
S>Я вот что скажу: в C++ вы можете ограничить себя тем подмножеством, которого вам достаточно и с которым вы не испытываете проблем. А когда этого оказывается недостаточно, то выйти за рамки. Или расширить для себя эти рамки.
Это не сработает, если вы работаете в команде.
S>А вот в C быстро достигается потолок. И все нужно делать ручками. Тратя свое мозговое вещество на то, что в C++ за вас бы делал компилятор. И не вылавливая потом баги, которые были допущены по недосмотру. Или потому, что уже никто не помнит, какие правила владения и очистки ресурсов были заложены в проекте когда-то давным-давно.
А не надо изобретать вычурные правила владения ресурсами, которые никто не может запомнить.
S>Так что возможность взять и со временем заменить btree<int> на btree<short> или на btree<long long> очень дорого стоит. А если туда еще можно запихнуть любой собственный тип, то вообще здорово.
Ну да, один раз в жизни может очень пригодиться.
Pzz>>но к практике вряд ли имеет отношение.
S>Видимо, у нас сильно разные практики.
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, _NN_, Вы писали:
V>>>но clang ошибку показал: _NN>>Тут предупреждение, а не ошибка компиляции. V>Но результат то неверный, — значит ошибка в этом месте
В C++ можно было бы написать шаблонный код и не ошибиться.
Кстати вот как это делать надо в C:
#define printf_dec_format(x) _Generic((x), \
char: "%c", \
signed char: "%hhd", \
unsigned char: "%hhu", \
signed short: "%hd", \
unsigned short: "%hu", \
signed int: "%d", \
unsigned int: "%u", \
long int: "%ld", \
unsigned long int: "%lu", \
long long int: "%lld", \
unsigned long long int: "%llu", \
float: "%f", \
double: "%f", \
long double: "%Lf", \
char *: "%s", \
void *: "%p")
#define print(x) printf(printf_dec_format(x), x)
#define printnl(x) printf(printf_dec_format(x), x), printf("\n");
Здравствуйте, antropolog, Вы писали:
A>Здравствуйте, so5team, Вы писали:
S>>b) таки приведете примеры реальных проблем с enable_if, с которыми может столкнуться обычный C++ разработчик (а не контрибьюторы STL, Boost, Folly, Eigen и др. хардкорных библиотек).
A>"обычный C++ разработчик" не знает об enable_if от слова совсем. И слава богу.
это не "обычный C++ разработчик", а "джуниор C++ разработчик". Знать желательно, использовать необязательно.
A>Т.к. шаблоны дальше библиотек общего назначения вылазить не должны.
никто не запретит вам так думать.
A>Давайте я перечислю чем С лучше C++.
A>- на порядок легче изучить
да! но элементарную алгебру тоже на порядок легче изучить чем высшую математику, не следует же из этого, что элементарная алгебра лучше высшей математики.
A>- на порядок проще анализировать ( как тулзами так и человеком )
нет! Мне на порядок сложнее. Часто встречался с такой ситуацией, что сам с-шник не мог понять, что он напрограммировал, особенно с параноидальным желанием с-шников писать код "быстро работающий" (преждевременная оптимизация), и "маленький" код, включая сокращения имен (писать без гласных) да так, что сами потом не могут вспомнить что эти имена означают и нужна ли теперь эта переменная.
Поэтому с-шники так боятся программировать в команде. Им кажется, что только они могут написать код без багов, а коллеги только его ухудшают по объёму, скорости и предсказуемости работы.
Но справедливости ради скажу, что "плохой плюсист" может написать код вообще нечитаемый и избыточно вычурный. Этим грешат начинающие плюсисты, для которых вычурность конструкций представляет большую ценность, нежели результат работы программы. Как говорил один из политиков: "ученость свою показать хочут".
A>- на порядок меньше результирующий бинарный код
не на порядок. Тогда asm -- наше всё.
A>- на порядок меньше аллокаций в куче ( из за общего подхода к разработке и интрузивных контейнеров )
Не на порядок. И вообще не является достоинством С. И есть ли такое требование в проекте -- не аллоцировать в куче? Если есть такое требование, то могу на С++ написать код не работающий с кучей, и вообще работающий только в кеше процессора, включая и все данные, аллоцированные в кеше процессора.
A>- стабильный ABI A>- элементарный байндинг к другим языкам
да.
A>- абсолютно предсказуемый execution flow (из-за отсутствия исключений)
проблема исключений не в их наличии, а в неправильном их использовании. Зачастую исключения используют как часть логики работы, что есть неправильно. Программист, не знающий что такое входной и выходной инвариант, базовая и строгая гарантии исключений -- не знает что такое исключения.
A>- унифицированный стиль разработки. Две программы на С гораздо более похожи по стилю, конвенциям и вообще подходу, нежели две программы на C++
больше определяется культурой разработки, стандартом предприятия, зрелостью программистов и не зависит, это С или С++ программа.
A>- практически все разработчики на C знают язык хорошо. "Разработчик C++" это очень размытое понятие, там где один использует "С с классами" второй вовсю использует шаблонную магию. Там где один использует new, другой использует vector. Там где один использует исключения, другой не использует. Итд.
да.
A>С не хуже С++, и не лучше. Это другой инструмент. Это скальпель. Вы им не нарубите лес, но сможете провести ювелирную операцию.
Здравствуйте, Vain, Вы писали:
S>>И? Как это же сделать на более простом C, в котором не будет enable_if и кучи другой хрени? V>ЗАЧЕМ? Какая задача решается, что не обойтись без такого?
Здравствуйте, _NN_, Вы писали:
S>>>И? Как это же сделать на более простом C, в котором не будет enable_if и кучи другой хрени? V>>ЗАЧЕМ? Какая задача решается, что не обойтись без такого? _NN>Попробуйте изобразить это на C: pointer_cast, safe_reinterpret_cast
_NN>Цель проста, обезопасить себя от ошибки на этапе разработки.
Цена таких ошибок не больше цены подобных в С++, поэтому я не понимаю почему их решение должно спасти вас от чего-то.
К примеру, я ни разу не столкнулся с проблемой лика или каста на pure C, это за 2 года что я на С активно писал. Была только одна проблема связанная с языком, — запись за массив. И то, была найдена на следующий день. Подавляющее количество ошибок было связано с самой прикладной областью и используемым API, но никак с языком. Остальные ошибки может и были, но я не помню про них, либо потому-что они решались на месте сразу, либо просто их значимость была настолько низкой, что не тянуло на минусы С. Зато прекрасно помню все проблемы которые и в С++ вылезали: дедлоки, кроссдедлоки, расстрелы памяти, неиницилазированные объекты и т.д. Не много то С++ от этого защитился, зато понаписано всяких шашечек выше крыши.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, _NN_, Вы писали:
_NN>Здравствуйте, Vain, Вы писали:
S>>>И? Как это же сделать на более простом C, в котором не будет enable_if и кучи другой хрени? V>>ЗАЧЕМ? Какая задача решается, что не обойтись без такого?
_NN>Попробуйте изобразить это на C: pointer_cast, safe_reinterpret_cast
_NN>Цель проста, обезопасить себя от ошибки на этапе разработки.
На С нет цели обезопасить себя. В этом и проблема что приходится "обезопасить себя" и это приводит к коду который решает не поставленую задачу, а создаёт дополнительную.
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, _NN_, Вы писали:
S>>>>И? Как это же сделать на более простом C, в котором не будет enable_if и кучи другой хрени? V>>>ЗАЧЕМ? Какая задача решается, что не обойтись без такого? _NN>>Попробуйте изобразить это на C: pointer_cast, safe_reinterpret_cast
_NN>>Цель проста, обезопасить себя от ошибки на этапе разработки. V>Цена таких ошибок не больше цены подобных в С++, поэтому я не понимаю почему их решение должно спасти вас от чего-то. V>К примеру, я ни разу не столкнулся с проблемой лика или каста на pure C, это за 2 года что я на С активно писал. Была только одна проблема связанная с языком, — запись за массив. И то, была найдена на следующий день.
Вы счастливчик. Мы в команде сталкивались и не раз.
V>Подавляющее количество ошибок было связано с самой прикладной областью и используемым API, но никак с языком. Остальные ошибки может и были, но я не помню про них, либо потому-что они решались на места сразу, либо просто их значимость была настолько низкой, что не тянуло на минусы С. Зато прекрасно помню все проблемы которые и в С++ вылезали: дедлоки, кроссдедлоки, расстрелы памяти, неиницилазированные объекты и т.д. Не много то С++ от этого защитился, зато понаписано всяких шашечек выше горы.
неинициализированные объекты в C++ решаются например так: auto_value
Здравствуйте, _NN_, Вы писали:
V>>Подавляющее количество ошибок было связано с самой прикладной областью и используемым API, но никак с языком. Остальные ошибки может и были, но я не помню про них, либо потому-что они решались на места сразу, либо просто их значимость была настолько низкой, что не тянуло на минусы С. Зато прекрасно помню все проблемы которые и в С++ вылезали: дедлоки, кроссдедлоки, расстрелы памяти, неиницилазированные объекты и т.д. Не много то С++ от этого защитился, зато понаписано всяких шашечек выше горы. _NN>неинициализированные объекты в C++ решаются например так: auto_value
.
really? и вы будете везде писать вместо простого int/float blablа — auto_value<int/float> blabla. А в глазах рябить не будет? Вот честно признайтесь.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, _NN_, Вы писали:
V>>>Подавляющее количество ошибок было связано с самой прикладной областью и используемым API, но никак с языком. Остальные ошибки может и были, но я не помню про них, либо потому-что они решались на места сразу, либо просто их значимость была настолько низкой, что не тянуло на минусы С. Зато прекрасно помню все проблемы которые и в С++ вылезали: дедлоки, кроссдедлоки, расстрелы памяти, неиницилазированные объекты и т.д. Не много то С++ от этого защитился, зато понаписано всяких шашечек выше горы. _NN>>неинициализированные объекты в C++ решаются например так: auto_value
. V>really? и вы будете везде писать вместо простого int/float blablа — auto_value<int/float> blabla. А в глазах рябить не будет? Вот честно признайтесь.
Если мне нужно чтобы всегда было инициализированно то да.
Вариант другой включить предупреждения компилятора и выставить "предупреждение как ошибка".
. V>>really? и вы будете везде писать вместо простого int/float blablа — auto_value<int/float> blabla. А в глазах рябить не будет? Вот честно признайтесь. _NN>Если мне нужно чтобы всегда было инициализированно то да.
Т.е. ты всегда так пишешь?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]