LINUX.ORG.RU

Почему в Qt не рекомендуют использовать исключения?

 


2

4

Волею случая сейчас делаю один проект на Qt, после Java хочется жирненько обмазать метод исключениями, а тут опаньки и такое вот написано, почему так?

http://qt-project.org/wiki/Coding-Conventions

Перемещено mono из talks

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

Файл-то ресурс. Но чтение-то при чем тут? Может пример приведешь? С асинхронным чтением, например.

anonymous
()
Ответ на: комментарий от nanoolinux

Пример чего?

Пример того, что написал я.

Что ты знаешь ни про std::vector <char> ни про std::unique_ptr <char []> ни бумбум?

Т.е. кастыли, неумение откатывать нормально конструкторы - вы просто юзаете на каждую байду по вложенному конструктору - гениально.

Мне даже интересно сколько оно будет раскручиваться на паре сотен вложений.

std::vector <char>

Крайне полезное знание.

std::unique_ptr <char []>

Рефкаунт, молодец.

На каждую байду надо ваять свой конструктор/деструктор. Удобства.

neosilyator

Да ты я смотрю смелый.

no memory leaks, neosilyator

Очень смелый, прям какими словами бросается «neosilyator», прям напротив слова «memory». Никто бомжей в плюсовых темах наместо не ставит - совсем нулёвые распоясались.

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

сказать «загрузи-ка мне файл и скажи когда закончишь пока я делаю другие дела»

Такое бывает нужно достаточно редко в достаточно специфических ситуациях. А в RL обычно файл загружают, чтобы сразу же как-то его использовать, и никаких «других дел» у программы в это время нет.

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

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

ddos3
()
Ответ на: комментарий от anonymous

Этот уютный RAII-фалик имеет тенденцию оказываться внутри такой же RAII-картинки. Типа делаем Image image(«pony.jpg») и получаем беду. Если вам и это непонятно то лучше идти и зубрить страуструпа с нуля и до забора.

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

Т.е. кастыли, неумение откатывать нормально конструкторы - вы просто юзаете на каждую байду по вложенному конструктору - гениально.

facepalm.jpg

Рефкаунт, молодец.

Нет там рефкаунта.

На каждую байду надо ваять свой конструктор/деструктор. Удобства.

Какую байду? Что не так с конструктором/деструктором?

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

Неосилятор, ты не отмазывайся, ты код показывай свой асинхронный, где RAII мешает.

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

Типа делаем Image image(«pony.jpg») и получаем беду.
зубрить страуструпа

Я что-то не припоминаю у Страуструпа про «беду». Можно детальнее раскрыть, в чем заключается эта «беда»? Желательно, с примерами кода, чтобы сразу все стало ясно.

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

и никаких «других дел» у программы в это время нет.

Ага-ага. У нас как раз есть. Рендеринг никогда не должен останавливаться и игрок вообще не должен знать что там что то грузится.

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

А вот тут вы не правы. Игры имеют такой объём данных что грузить их синхронно сейчас вообще нельзя. Минимальный объём позволяет только показать логотип, а остальное требует полной асинхронности. Драйвера кстати любят когда графические ресурсы генерируются в много-много потоков.

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

Ну если ты утверждаешь, что unique_ptr - это рефкаунт, а что использование vector и др. стандартных классов - костыль, то кто ты еще, как неосилятор? Это просто факт, а не оскорбление.

anonymous
()
Ответ на: комментарий от ddos3

«Беда» заключена в том что этот код будет исполняться в главном потоке и занимать целые милисекунды и десятки милисекунд. И нафигачить такого говна очень легко.

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

Ты мне покажи как я могу сделать что либо асинхронно сохранив преимущества RAII. Ведь если я сделал File* file = File.OpenAsync(«pony.jpg») - я не получаю файла, я даже не знаю есть ли он на диске в этот момент. Чисто запрос «открой мне файл когда нибудь в будущем». И никакого RAII тут нет вообще.

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

код будет исполняться в главном потоке и занимать целые милисекунды

Ну, если следующей строкой в коде идет drawImage(image.rawData);, и в промежутке программе все равно нечем заняться, то деваться некуда. И в большинстве случаев, это именно то, что происходит.

Игры имеют такой объём данных что грузить их синхронно сейчас вообще нельзя.

Я давно уже просил пруфоф и цифр, и раз уж речь зашла про игры, повторяю просьбу: на сколько ассинхронное I/O ускоряет загрузку игровых ассетов на стандартной десктопной машине под виндой с одним диском SATA, отформатированным в NTFS? Как на скорость влияет смена ОС/ФС?

Драйвера кстати любят когда графические ресурсы генерируются в много-много потоков.

Драйвера «любят», когда шина памяти загружена на 100%. Во сколько потоков это достигается, значения не имеет.

ddos3
()
Ответ на: комментарий от anonymous

Мне даже интересно сколько оно будет раскручиваться на паре сотен вложений.

Так проведи тест! Посчитай наносекунды!

На каждую байду надо ваять свой конструктор/деструктор. Удобства.

Ты упорот. Ничего ваять не надо, потому-что уже есть из коробки. Деструкторы тут вообще не в тему. Иди в тред про липс.

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

Более того, тут не только RAII нет, тут нет даже RA. Но где-то в другом месте должен быть код, который попытается использовать pony.jpg после загрузки. Вот там RAII вполне может быть. Но опять же, все зависит от того, как написать.

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

Цифр там нет (кроме 6-7 МБ/с с диска, но они не релевантны). Сравнения скорости синхронного/асинхронного доступа тоже нет. Этот же эксперимент можно повторить с классическим синхронным доступом в рабочем потоке, и тоже будет «ни единого разрыва». Меня же интересует лабораторное сравнение производительности async i/o и «классического» i/o.

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

Ты слишком много хочешь от спп. Накатай обёртку вокруг какого-нибудь man aio, деструктор которой вызывает aio_cancel и будет тебе именно то, что нужно.

Нужна тру ассинхронность - юзай какой-нибудь go/rust/erlang.

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

юзай какой-нибудь go/rust/erlang.

Они не дают контроля над другими критическими вещами. На свете вообще нет ни одного хорошего языка.

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

юзай какой-нибудь go/rust/erlang.

Они не дают контроля над другими критическими вещами

Над какими вещами не дает контроля Rust?

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

сли что, ворд исправно падает и исправно предлагает восстановить всю работу при следующем запуске (причём неудачное восстановление можно откатить).

Ага. И восстанавливает почти нифига. Знаем, плавали.

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

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

Пока что ты мне рассказываешь, какое клевое async i/o, но при этом все твои доводы сводятся к тому, что «оно быстрое» и «оно плавное». Первое требует доказательств в виде цифр, предоставить которое ты отказываешься, а второе с тем же успехом (и даже лучше) достигается выносом стримера в отдельный поток.

Все это напоминает сектантскую пропаганду и пахнет столь же дурно. Так что повторю снова: давай ссылки на серьезные исследования, или признай слив.

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

Над какими вещами не дает контроля Rust?

Практически ни над какими, чтобы программист ненароком себе чего не отстрелил, насколько я помню прежние обсуждения :) Хотя, в unsafe режиме он столь же взрывоопасен, как с++, но не так удобен.

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

Значение имеет плавность и отсутствие затыков.

Так это уже требования для рт систем. Только там не всё так просто.

А для игродела, что делать если твой файл так и не открылся за 5 минут пока юзеру показывали прогресс бар или заставку? Тебе уже надо показывать меню, а данных нет. Ассинхронность эту проблему не решит например. Другое дело отображение не сильно важных компонентов сцены, как кустики во второй халве, но если ты эту задачу решаешь при помощи раии ты явно что-то делаешь не так.

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

Над какими вещами не дает контроля Rust?

Практически ни над какими [...] насколько я помню прежние обсуждения

Больше вопросов нет.

Хотя, в unsafe режиме он столь же взрывоопасен, как с++, но не так удобен.

Очевидно, вывод тоже сделан на основании чтения обсуждений.

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

ни над какими, ... насколько я помню прежние обсуждения :)

Аналитично.

anonymous
()
Ответ на: комментарий от uuwaan

Бинарная совместимость библиотек в случае плюсов зиждется на ABI, заимствованном из C и том факте, что таблица виртуальных методов разными компиляторами создаётся в едином виде.

Это всё, конечно, хорошо, но мало кто так делает. Qt вот, например, так не делает и не имеет никакой совместимости. Плюсовая бибилиотека с «совместимостью» это обычно ужас из шаблонов + немного обвязки через си.

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

facepalm.jpg

Что-то не так. Какие же вы все тупые - не согласен - курлыкай, объясняй мне в чем я не прав.

Нет там рефкаунта.

В данному случае нет, ибо юзается «сырые указатели», если ты будешь инициализировать unique_ptr"ом - он будет нужен, а без него нет смысла.

Какую байду?

Ещё раз, т.к. вы не можете отслеживать прогресс в теле конструктора - вы не можете юзать деструктор, в котором больше одно варианта отката конструктора.

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

Ексепшн же просто стопает исполнения следующих конструкторов в конструкторе и их деструкторы + деструктор того, в котором ексепшн. Это какбэ убирает проблему.

Что не так с конструктором/деструктором?

Я уже показал что не так. Вы не моежете юзать деструктор с более чем одним вариантом отката.

Если же юзать с одним, то нужны рефкаунты. Монжо юзать(и все юзают) другой кастыль - кучу, которая позволяет передавать объект без дёрганья деструкторов, ибо они ручные(конструктор/деструктор).

Т.е. конструкторы не являются тем, что от них задумывали - они не инициализируют объект - они инициализируют переменную. Он этого не умеет - в этом фейл.

int fd = open() after close();//т.е. деструктор у вас обычная обратная функция, которая дёргается. 
anonymous
()
Ответ на: комментарий от ranka-lee

Это не меня надо спрашивать, а икспэртов, вроде tailgunnerа.

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

Какая разница будешь ты ждать тут или на open? Вообще асинхронный файловый ввод вывод в линуксе нормально не работает и во всех проектах либо забивают на эту проблему или используют отдельный тред-пул для файлового i/o.

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

юзается «сырые указатели»
в котором больше одно варианта отката
конструктор с один вариантом отката
конструкторы... Он этого не умеет

Я, конечно, не граммар-наци, но читать твои творения просто невозможно. Я уже не говорю о запятых и прочих знаках препинания, но слова в предложении должны хотя бы как-то сочетаться между собой. Выглядит так, что ты очень торопишься что-то сказать, но в твоей речи слишком много лишних слов, оговорок, кривляний, прыжков с середины одной мысли в середину другой. И в результате смысл ускользает (если от там был, конечно).

ddos3
()
Ответ на: комментарий от anonymous

объясняй мне в чем я не прав.

Слишком долго. Ты не знаешь/не понимаешь основ программирования.

если ты будешь инициализировать unique_ptr"ом - он будет нужен

Кто? рефкаунт? Рефкаунт никак не связан с uniqe_ptr'ом.

Ещё раз, т.к. вы не можете отслеживать прогресс в теле конструктора - вы не можете юзать деструктор, в котором больше одно варианта отката конструктора.

Я в теле конструктора могу отслеживать все, что захочу отслеживать. Деструктор не вызовется, если в конструкторе что-то пойдет не так и это правильно. Деструктор, в котором потребовался более, чем один вариант разрушения, скорее всего, неверно спроектирован. Или вы не учли, что это часть состояния объекта.

Т.е. конструкторы не являются тем, что от них задумывали - они не инициализируют объект - они инициализируют переменную.

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

кучу, которая позволяет передавать объект без дёрганья деструкторов

куча нужна для динамического размещения в памяти. А вы о чем?

anonymous
()
Ответ на: комментарий от nanoolinux

Так проведи тест! Посчитай наносекунды!

Как же ты кукарекаешь не понимая даже о чем. Эти нулёвые балаболы такие смешные, всегда любят курлыкать о том, в чем нихрена не понимают.

Да ладно там что-то понимать - пацан даже не представляет величин - не знает что такое наносекунда и просто кидается словами.

Ты упорот.

Датычто.

Ничего ваять не надо, потому-что уже есть из коробки.

Да ладно - я писал уже выше(Почему в Qt не рекомендуют использовать исключения? (комментарий)), всё что у тебя есть из коробки - это дёгать хип форфан.

Вот нам надо открыть файл, а потом его закрыть - ты не можешь передать открытый файл в классе вниз по вызовам. Ты не можешь передать ссылку на стек - ты должен скопировать класс без вызова деструктора(да, да - move()) - это нужен костыль который следит за этой байдой.

Ты же, как и обычный нулёвый балабол юзаешь хипу, с её ручными конструкторами-деструкторами. А эмулируешь move() через unique_ptr, в котором впилен кастыль в виде рефкаунта, чтобы он не удалял данные, а декрементировал рефкаунт.

Т.е. ты ту ущербность конструкторов/деструкторов, о которой я сказал, устраняешь десятью вложенными убогими кастылями, даже не понимая как они работают. Причем сейчас мы уже говорим о другой проблеме классов - это передача класса вниз по вызовам - т.е. вернуть из функции.

Твои пацаны пилят &&, а ты даже не понимаешь в чем проблема - истинный плюсовик.

Деструкторы тут вообще не в тему. Иди в тред про липс.

Всё в тему, просто до тебя всё ещё суть темы допереть не может.

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

unique_ptr, в котором впилен кастыль в виде рефкаунта

Судя по невежеству - царь снова с нами?

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

вы не можете юзать деструктор, в котором больше одно варианта отката конструктора


class Recoil
{
   function <void ()> f;
   bool discharged;
  public:
    Recoil(const function <void()> &f): f(f), discharged(false) {}
    ~Recoil() {if (!discharged) f();}
   void discharge() {discharged = true;}
};

...

Test::Test()
{
   std::list <Recoil> l;
   ..
   l.push_back([] () {твой неосиляторский откат 1;}
   ....
   l.push_back([] () {твой неосиляторский откат 2;}
   ...
   for_each(l, [] (Recoil &r) {r.discharge();}); l.clear(); //да ну нафиг, давай с начала
   ...

  l.push_back([] () {твой неосиляторский откат 10;}
    ....

  // теперь все хорошо и
  for_each(l, [] (Recoil &r) {r.discharge();})
}

Кушай дальше борщ С с классами и сырыми указателями. Сыроед.

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

что такое наносекунда

Я пишу для железа, которое меряет пикосекунды. Это железо можно найти почти на любом синхротроне мира, даже роскосмос один девайс купили в прошлом году. Так что я тебе сейчас расскажу что такое наносекудна, пустозвон. Вали кушать борщ со своим нулёвым коНпеляротом и компанией, метросексуал.

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

Слишком долго. Ты не знаешь/не понимаешь основ программирования.

Конечно.

Кто? рефкаунт? Рефкаунт никак не связан с uniqe_ptr'ом.

рефкаунт основа uniqe_ptr"а.

Я в теле конструктора могу отслеживать все, что захочу отслеживать.

Нет. Я уже привел выше по треду пример, в котором твоё отслеживание проявляется во всей красе.

Ещё раз - у тебя три malloc() в конструкторе и три free() в деструкторе - нука сделай мне так, чтобы free() исполнялся столько же раз, сколько malloc(). Без «сишной лапши на ифах» с сохранением стейта.

Деструктор не вызовется, если в конструкторе что-то пойдет не так и это правильно.

Датычто? И что же это нетак? вызов ексепшна?

Деструктор, в котором потребовался более, чем один вариант разрушения, скорее всего, неверно спроектирован.

Да ты гений, алёша. Ты понимаешь, что твоё «проектирован» - это вложенные конструкторы, а вкладываются они по причине того, что твои конструкторы говно, а говно они, ибо не могут отслеживать прогресс.

Т.е. ты сводишь деструктор к просто обратной функции для БАЗОВОЙ ПЕРЕМЕННОЙ(типа). Он обратная функции инициализации ОБЪЕКТА.

Конструкторы конструируют объект.

А вот тут ты зафейлился. Не объект, а базовый тип. Чтож вы все такие глупые.

До конструктора мы имеем просто кусок памяти, после - объект.

Не объект - конструктор в твоём случае инициализирует лишь переменную базового типа.

Деструктор делает обратное - берем объект, обрабатываем его уничтожение нужным образом, после чего имеем просто шматок памяти.

Да ты я смотрю логик отбога, алёша. Ты понимаешь, что объект состоит из составляющих и не может обработать их в деструкторе, ибо это больше одного варианта расрушения. Конструктор/деструктор обрабатывает побочные эффекты. Объект - это может быть много побочных эффектов.

Когда у тебя 2побочных эффекта - у тебя 2варианта расрушения. Логика внутри деструктора без побочных эффектов не имеет смысла. Ты же, алёша, говоришь, что «2 варианта нельзя».

Ты же делаешь кастыль, когда каждый побочный эффект засовываешь в свой деструктор - у тебя уже не ДЕСТРУКТОР «уничтожает» ОБЪЕКТ, алёша, а АВТОВЫЗОВ ДРУГИХ ДЕСТРУКТОРОВ. А твой деструктор у объекта НАХРЕН НЕ НУЖЕН И НЕ ИМЕЕТ СМЫСЛА.

куча нужна для динамического размещения в памяти. А вы о чем?

Очередной нулёвый студент, который даже не понимает о чем говорит. Да нахрен, динамического, обоже - это просто гении.

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

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

Ты ошибаешься. Тебе 100500 раз об этом сказали уже разные люди, но ты твердишь.

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

рефкаунт основа uniqe_ptr"а.

Нет рефкаунта в unique_ptr.

Ещё раз - у тебя три malloc() в конструкторе и три free() в деструкторе

Не будет у меня такого конструктора.

Датычто? И что же это нетак? вызов ексепшна?

Именно

А вот тут ты зафейлился. Не объект, а базовый тип. Чтож вы все такие глупые.

Конструктор конструирует тип? Да еще и базовый? Что ты несешь опять? Завязывай с наркотиками.

Ты понимаешь, что объект состоит из составляющих и не может обработать их в деструкторе, ибо это больше одного варианта расрушения.

Может и обрабатывает. Ты просто не в теме, но лезешь. Несешь полную чушь. Иди учись.

anonymous
()
Ответ на: комментарий от nanoolinux

Да я смотрю ты решил меня поучить. Это так мило.

Только ты даже запилить нормально не осилил - твой эксепшн разве не стопает конструктор?

Зачем нужна эта бездарная байда?

for_each(l, [] (Recoil &r) {r.discharge();}); l.clear(); //да ну нафиг, давай с начала

std::list <Recoil> l ты не осилил засунуть в свой говнокласс и просто делать l.push_back([] () {твой неосиляторский откат 1;}

Если ты, обезьянка, думаешь что ты меня своими жалкими потугами удивишь - маловероятно.

Ну и да - это кастыль, причем не рабочий.

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