- 1
- 2
std::string cmd = "some command";
Socket.Write( cmd.c_str(), strlen( cmd.c_str() ) );
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+5
std::string cmd = "some command";
Socket.Write( cmd.c_str(), strlen( cmd.c_str() ) );
сишные плюсЫ
>версия стл не гарантировала что 0
гарантии появились в c++11
глядишь через лет пять они наконец введут pop_*() методы возвращающие элемент...
> http://www.cplusplus.com/reference/string/string/pop_back/
> > Return value: none
Для контейнеров 146%, что никогда не введут. У таких методов начинаются проблемы с безопасностью исключений, если копирующий конструктор элемента может кинуть исключение. Если кратко - можно по дороге необратимо проебать элемент. Почитай "решение сложных задач на c++" Саттера.
везьде и у всего есть какие-то проблемы. (давайте выкинем поинтеры из С/С++ - с ними ведь так много проблем!)
в контексте. глупый и бесполезный std::string::data() есть. а популярный и нужный и то что на 90% С++ проектов народ сам ручками пишет - нету.
> Почитай Саттера.
я по работе уже достаточно отмазок слышу почему через ж сделано и/или криво работает. а тут вы мне еще и книгу специально для этого почитать предлагаете?...
ЗЫ с такими аргументами ("think of children!") вам надо на жабу перебираться. там себя как дома будете чувствовать.
ЗЗЫ в Qt - QList::takeLast()/::takeFirst(). и небо не упало на землю.
> на 90% С++ проектов народ сам ручками пишет
А так ли нужен этот возвращающий значение push_back? Атомарности он один хер не даст. А "обработал через back() и дропнул через pop_back()" будет даже эффективнее, чем копировать результат pop_back() во временную переменную... Так хочется сэкономить одну строчку?
"я вас умаляю."
говно с двумя вызовами мешает писать вот такой на первый взгляд тривиальный код (пользуясь стл-ифицированой номенклатурой Qt):
вместо этого надо извращатся:
ы? кто из нас тут брызжет оправданиями почему нет?
> И всего на строчку длиннее.
и семантика не та, и два выражения вместо одного.
Ну да. Полная транзакционность против говна, которое проябывает элемент при исключении в push_back или конструкторе копирования ;) Или такая семантика и требовалась? :)
Что с семантикой не так? Поясни.
если у тебя проябывает - то это у тебя руки кривые.
У тебя в проекте исключения отключены? Или "память же резиновая, поэтому new всяко не будет кидать исключение, да и конструктор копирования - тоже, и так сойдёт"?
потому что ты упорно на коммент "на практике работает" пытаешься протолкнуть "но теоретически что-то может работать не правильно" ответ.
На практике и возврат адреса стековой переменной работает. В некоторых случаях даже годами...
Многопоточные алгоритмы по тому же принципу пишем? Счастливой отладки.
new падает с bad_alloc? Уберём его вызовы, хуй с ними.
Топор - лучшее средство от головной боли.
и какое отношение имеет то что ты в твоем коде исключения не обработал к моему коду?
то ли вы все идиоты, то ли мы говорим о разных вещах.
А bad_alloc во время push_back'а или конструктора копирования элемента в твоём c2.push_back(c1.take_last()) безвозвратно проябывает переносимый элемент.
P.S. Или и c1 и c2 - связные списки из POD'ов, а прога однопоточная? Тогда bad_alloc в данном push_back'е вроде как действительно не будет возникнуть на практике.
Ну точнее не POD'ов, а любых типов, которые не выделяют память в конструкторе копирования.
> возникнуть
возникать
1. "конструктора копирования" если у тебя конструкторы бросают исключения - то сам идиот.
2. "bad_alloc во время push_back" - только в случае если у тебя где еще нет ссылки на этот элемент. или не транзакционно-защищенный код. или свой GC прикручен. или это сообщение выделеное из пула которое будет перепослано если не придет ответа. или это вообще тестовая прога, где допустимо что все повалится на unhandled exception в случае FAILED теста.
у меня есть чувство что вы начитались каких книг и толкаете мне теории. в то время как я реально на практике фиксил (и white box тестировал) проги что бы они были 100% STL exception safe.
это опять же не отменяет полезности take_last() потому что если на проектах где требуется надежность кода (в тех редких местах где С++ вообще разрешен) STL в принципе избегают. а для всего остального, take_last() это "мелочь но приятно".
Okay. Так и запишем - авторы STL и boost - идиоты. Все до единого.
И как же практики сообщают об ошибках во время конструирования? Джвухфазной инициализацией (foo a(...); if (a.init()) ...) али флагом каким-нибудь (foo a(...); if (a.isValid()) ...)?
да. и таже фигня для деструкторов. и init()/finish() не должны бросать исключений. иначе, по моему опыту, большие модели данных с 100% верностью создать/удалить без мемори ликов почти невозможно.
я это правило с прокта на проект таскаю. народ жалуется и жужжит только до Н-го раза когда с красивым ОО-шным кодом лажаются. и пока лажались все.
если нужна 100% защита от мемори ликов, то еще часто все объекты складываю в глобальные/per-transaction списки, что бы все можно было поодиночке удалить в конце сессии/транзакции/этц.
А если объекту надо заinit'ить 3-4 поля - по-сишному юзаем goto / do {...} while (), чтобы ничего не забыть за finish'ить при откате... Классический exception free c++.
В итоге делаем руками всё то, что аккуратный код с исключениями из конструктора дал бы бесплатно и с тем же уровнем надёжности.
да? и какова длина гирлянды из catch()ей у ваших try'ев?
как я и написал:
> > и пока лажались все.
кто-то что-то где-то забывает. где-то кто-то забывает какой эксепшн обработать - и потом неделями народ ищет эти ошибки.
фишка моего подхода что он туп как валенок. его можно с легкостью проревьювить и протестить буквально за минуты. что оставляет все остальное время на работу с основной логикой прогаммы.
Да там вся фишка в том, что если RAII соблюдается, если деструкторы и ещё несколько методов не кидают исключений, то все откаты/освобождения работают автоматом, в правильном порядке и без портянок if'ов/catch'ей. А try/catch стоят только там, где ты реально что-то полезное кроме отката, освобождения и возврата хочешь сделать (а это не так часто, и 90% вот этих твоих ифов просто откатывают состояние и передают код ошибки на уровень выше, где он делает то ж самое). Ну и где-нибудь на самом верху, чтобы зафейлить запрос/сессию/всю прогу.
> какова длина гирлянды из catch()ей у ваших try'ев?
Любой try/catch для освобождения ресурсов по определению считается говном и рубится на ревью. Поэтому никаких гирлянд нету, остаётся только основная логика :)
что работает только тогда когда RAII вообще применим. на простой фигне оно катит. но если у тебя есть хоть насколько-то нетривиальная модель данных, то цикличиские зависимости данных нередки и RAII отдыхает.
и RAII в принципе отдыхает если у объекта нетривиальный life cycle.
не, да, можно враперов и адаптеров нагородить, но это только добавляет сложности и снижает тестируемость.
> Поэтому никаких гирлянд нету, остаётся только основная логика :)
спорить не буду. у вас похоже данных поменьше, модели попроще и ресурсов в избытке. если работает - то почему бы и нет.
Ну да, там жопа начинается когда нет "вертикали власти" - ациклического графа владения. Но этот случай без GC в какой-то форме, хотя бы минимальной, вроде вообще никак не разрулить...
RAII/не RAII там уже особо не влияет. Один хуй без сканов не видно, чего можно погрохать.
> нетривиальный life cycle
Можно на конкретный пример посмотреть?
нет. но на самом деле, как я говорил выше, ты просто больше не полагаешься на вертикаль, а просто дополнительно держишь объекты в специальной плоской коллекции, по которой их можно потом махом удалить. (народ это называл "repository".)
> Можно на конкретный пример посмотреть?
недавно были грабли по типу: разрушение RAII объекта тригерит асинхронное действие, с которым потом конфликтует инициализация нового объекта. теоретически, объект надо было подымать в контекст уровенем выше. практически, как такого, этого контекста просто не было. (пара примеров: открытие/закрытие серийного порта (открытие делает инициализацию которая может убить данные которые еще в HW очереди сидят); синхронное vs асинхронное проигрование звукового файла, когда некоторые потоки не хотят ждать когда файл до конца доиграет.)
Ну так это и есть та самая вертикаль, т.к. только ссылки из неё удерживают объекты от смерти ;)
> некоторые потоки не хотят ждать когда файл до конца доиграет
Я это решал дополнительным объектом Player. Основная идея - плеер держит shared_ptr на файлы, которые он играет/будет играть следующими. Не хочешь ждать - просто отпусти файл и всё само удалится когда доиграет или воспроизведение отменят.
> которая может убить данные
Здесь сложно ответить навскидку. Надо больше контекста. В том числе - а не похуй ли нам на неполный пакет, который сейчас трансмиттер выплёвывает? Порт ведь не от хорошей жизни резко закрыли без flush/ack. Значит какая-то ошибка была и пакет скорее всего один хер будет неполный, даже если инициализация ничего не потрёт.
нет. там где я это делал, это была "горизонталь". вертикалью там была извратная вложеная/древовидная структура данных.
> Порт ведь не от хорошей жизни резко закрыли без flush/ack.
там все было слегка сложнее. это было real-time и тайминг операций был известен. поэтому и не было флаша. но. между рил-тайм блоками, там были еще и нормальные интерактивные фазы. переход из рил-тайм в интерактив убивал данные из рил-тайм фазы.
это было просто последствие слепого применения RIAA "патаму шта синглтоны это плохо!". в нормальном случае, без мудрения, просто делается глобальная инстанция серийного порта, раз открывается и никогда не закрывается. но они там увидели проблему с размером выходного буффера, и попытались ее пофиксить с динамически выделяемой памятью.
А почему бы просто не дождаться, пока трансмиттер всё передаст? И только тогда считать риал-тайм фазу законченной и закрывать порт?
> слепого применения RIAA
+1.
> глобальная инстанция серийного порта, раз открывается и никогда не закрывается
Ну тоже не всегда айс. Иногда хочется не убивая сервер поболтать с железками через какой-нибудь minicom. А такая схема не даст. Хотя от задачи. конечно, зависит.
ну нечто в этом духе и было решением. в рил-тай режиме просто было не желательно ждать, а в интерактивном режиме просто использовались те же самы классы что и в рил-тайм.
> Иногда хочется не убивая сервер поболтать с железками через какой-нибудь minicom. А такая схема не даст.
такое редко бывает нужно. в общем случае проще какой cisco-style телнет интерфейс на сокетах прикрутить (или ту же zebra взять). (но в моем конкретном случае это было на встроенной железке с 256К памяти, где эзернетом и не пахнет.)
Т.е. деструктор RAII объекта должен вызываться когда объект никому не нужен, а не только текущей процедуре. Тогда всё, внезапно, становится простым и наглядным. И в деструкторе остаётся самый минимум.
Ну-ну. Миллионы строк кода без двухфазового создания объектов. Проблем с этим никогда не было.
Кстати, семантика конструирования объектов в условии исключений - одна из тех вещей в С++, которые сделаны правильно.
+
>если у тебя конструкторы бросают исключения - то сам идиот.
Самое смешное, что bad_alloc приходил именно из конструктора std::istringstream.
> Самое смешное, что bad_alloc приходил именно из конструктора std::istringstream.
ну это же STL. народ пальцы себе ламает у виска крутить уже десятилетиями.
за деньги делает сендвичи из разных сортов говна
а сёма не делает ничего, он невостребован
Сёма парсит сайты на питоне. Видимо таки востребован.
Конечно. Сегодня как раз на работе пару раз на асме умножал сдвигами на 8 и пару раз делил на 16.
работал я с середины 3 курса, ипотеку мне ещё 8 лет выплачивать, а работаю я по 10+ часов в день
просто работать на работе надо, за деньги, которые дают, чтобы научили и заплатили через год больше, а не дома сидеть хуи пинать и считать, что жавоёбы/гитлерлинуксдрочеры/пыхомакаки всё твоё сало зъилы
на первой работе (инженер саппорта инет-провайдера) я зарабатывал $300 в месяц при 42-часовой рабочей неделе, совмещая с очным в/о, и ничего, не сдох
Кому надо? Зачем надо? Ты для себя работаешь, а не для меня. Так что мне похуй кем и где ты работаешь, меня интересует лишь чем ты реально можешь мне помочь. Понты можешь кидать перед людьми, которые от тебя материально зависят, выслушают, куда денутся.
> жавоёбы/гитлерлинуксдрочеры/пыхомакаки всё твоё сало зъилы
Мое сало при мне в магазине. Тут же сайт говнокода? Так почему я не могу упомянуть, что в языке х нету весьма очевидной библиотеки, что синтаксис отстает на 5-10 лет? Про пыхомакак/дельфодрочеров тут пишут и без меня, какие у тебя ко мне претензии? Или ты считаешь, что твои узкие проблемки по работе кого-то за ее пределами интересуют?
Я не пойму - тут стало модным доебываться до людей которые более или менее кодят для себя?
поправлено для соответствия тематике сайта
Пидарок это у тебя потолок? 400 евро? Это блядь меньше чем я на пиво трачу в месяц.
Он же не сказал, что пьёт потом это пиво. Может, он покупает пиво и отпускает его на волю?
хорошо сидеть дома и дрочить ф5 в браузере
совсем не то же самое, что работать
а чего ты сказать то хотел, никто не понял
что у тебя такая жизненная позиция сидеть на жопе ровно, пока пенсия не придёт? да дело твоё
Я хотел сказать - не надо судить по вещам в которых ты не шаришь. Я ж вот не утверждаю, что расия - страна клинических ебанатов по вашим видео с регистраторов. А, это наверно такой ымперский комплекс - да хуле там, я все знаю.
чего тебе всё мало то?
рассказывать о том, что даже моя жена в 7 раз больше твоего пособия зарабатывает - да какой мне профит, накой самоутверждаться за твой счет? детей обижать.
работать иди, опёздол
Еще раз, тут были люди писавшие под себя, тот же стертор, на еще более устаревшем говне. Что у вас загорелось-то?
<green>Ага. Там, если какие проблемы в программе случились - фреймворк серанул в qDebug() мессагу и дальше исполняет. Ляпота!</green>
Qt - не образец, а местами даже двадцатилетнее говно, которое лежит и каменеет под грудой легаси. И мне очень жаль, что оно настолько популярно.
Хотя noexcept в них скорее норма, чем исключение.
?