LINUX.ORG.RU

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

 


2

4

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

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

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

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

Ещё раз: там нет подсчета ссылок, поскольку никто не считает ссылки и вообще счётчик ссылок отсутствует. Передача владения не считает ссылки, а передаёт владение. Впрочем, что можно доказать человеку, считающему атеизм верой в богов.

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

Вперёд пилить unique_ptr без рефкаунта и его эмуляции.

Так уже написан. Берю любую реализацию и смотри. Покажи там счётчик ссылок.

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

Некоторые так и пишут в доках «исключения устраняются на этапе разработки»... Кому потом это сопровождать - колыхает мало:) Но икается им наверное почти постоянно.

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

Эм. Можете раскрыть тему? Как какой-либо программный проект может быть аргументом в данном случае?

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

где рабочее

В Караганде. Давно уже работает без твоих сопливых вбросов, чучело.

Покажешь же мне, да? Я жду пруфец терагерцового счётчика.

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

не рядовой обезьяной с авркой

Жуй свои сопли дальше. Я тебе ничего не доказываю, оно и так с авркой в паре работает. Но тебе не понять, ты всего лишь инопланетный дегенерат.

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

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

А в чем проолема?

class Foo {
public:
	Foo(): m_fooBar(0), m_whateverYouWant(0), m_oops(0)
	{
		// you could create members and raise exceptions as many as you want
	}

	~Foo()
	{
		delete m_fooBar;
		free(m_whateverYouWant);
		free(m_oops);
	}

private:
	class FooBar *m_fooBar;
	void *m_whateverYouWant;
	void *m_oops;
};

мимоборщевик

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

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

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

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

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

Как какой-либо программный проект может быть аргументом в данном случае?

Как? Фактом своей работоспособности простоты и наглядности.

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

Ещё раз: там нет подсчета ссылок, поскольку никто не считает ссылки и вообще счётчик ссылок отсутствует.

Как так не считает - что же есть флаг, который указывается передал ли ссылку поинтер или нет?

Ещё раз для даунов - счёт может быть и до одного. Рефкаунт не считает ссылки, даунёнок - это флаг владения. Ты реально настолько туп, что не понимаешь это? Сам счётчик это кастыль, чтобы хранить множественное состояние.

Суть его в «владею только я», «владею не только я». Тут же заменяется «владею не только я» на «не владею», ибо когда владею не только я - я не владею, ибо передача владельца.

Это такой же рефкаунт. Хотя для дауна рефкаут - это переменная с названием «рефкаунт», что с дауна взять? А если я назову её «вася» она уже будет не рефкаунтов, а васей? Если я рефкаунт засуну в указатель - тоже не будет рефкаунта?

Как будет не лень - поэксперементируем над твои пердаком.

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

А что это? А что же в нём изменяется, как называется тот флаг, что отслеживает владение.

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

В Караганде. Давно уже работает без твоих сопливых вбросов, чучело.

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

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

Что тебе разжевывать - там максимальный резолюшн таймер 10ps - это не пикасекунды, говнарь и счётчик не терагерцовый.

Я всё больше убеждаюсь, что поломойка название подсмотрела, а что и зачем не знает.

Жуй свои сопли дальше. Я тебе ничего не доказываю, оно и так с авркой в паре работает. Но тебе не понять, ты всего лишь инопланетный дегенерат.

Полезность, насколько я понял оно снимает сигнал с ноги и передаёт аврке. Дак в чем сложность-то? Чем эта считалка отличается от дефолтной в авр"ке?

Дак ты обычная обезьяна, а резолюшн таймера тебе скилла не даёт. Хотя ты скорее всего и говно аврку не щупал, а полы моешь. Неосилил «голые указатели», решил учить кресты и всем доказывать, что «голые указатели» говно?

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

Да мало этого - ты понтовался своей портянкой, но когда понял, что она не работает начал юлить как 5-ти летний. «Я мастер крестов. Где? Я уже всё сказал и доказал - там вон написано. Но ведь там написано, что ты мастер говна? Да не, ты просто не понял - это 100% мастер крестов, отвали от меня „ко-ко-ко я гордая поломойка“». Кулстори.

Причем заметь как ты сначала начал со мною спорить, кидаться словами «неосилятор». Теплилась надежда, что вот оно - вот я покажу этому анонимусу мой скилл, но не фортануло. И твоя риторика тут же сменилась как пошло «Царь в треде». Ты уже понял, что спорить бесполезно и поплыл на «я дурак? Почему? Да все так говорят в классе - ифна сотка - ты 100% дурак».

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

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

Вперёд пилить unique_ptr без рефкаунта и его эмуляции.

Где тут счетчик ссылок или его эмуляция:

template<typename T>
class uniq_ptr
{
public:
    explicit uniq_ptr(T *ptr = nullptr)
        : p(ptr)
    {
    }

    ~uniq_ptr()
    {
        delete p;
    }

    uniq_ptr(const uniq_ptr&) = delete;
    uniq_ptr & operator = (const uniq_ptr &) = delete;

    uniq_ptr(uniq_ptr && other)
        : p(nullptr)
    {
        swap(other);
    }

    uniq_ptr & operator = (uniq_ptr && other)
    {
        uniq_ptr tmp(std::move(other));
        swap(tmp);
        return *this;
    }

    uniq_ptr & operator=(std::nullptr_t)
    {
        uniq_ptr tmp(*this);
        return *this;
    }

    void swap(uniq_ptr & other)
    {
        std::swap(p, other.p);
    }

    T * operator -> () const
    {
        return p;
    }

    T & operator * () const
    {
        return *p;
    }

private:
    T *p;
};
? Тыкни носом. Только давай серьезно, я прям тут писал, мелкие ошибки и упрощения не в счет.

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

Тут же заменяется «владею не только я» на «не владею»

Нет. Ты этим объектом всегда владеешь.

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

мимоборщевик

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

Читай условие задачи, не? Даже бомжи до тебя там не фейлили и хоть что-то рабочие предоставляли.

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

А что же в нём изменяется, как называется тот флаг, что отслеживает владение.

Нет никакого флага.

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

Так я ничего против си не имею. Я жду аргументов против исключений и C++

Провокация к написанию уродливого тормозного кода.

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

царь, всем насрать на твои рефкаунты, съеби из треда быстро, решительно.

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

Счетчик ссылок является частью метаинформации, привязанной к объекту, а не к ссылке. В то время как проверка валидности указателя часть работы самой ссылки.

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

Да уже лет 20 на C++ пишу. Проблем гораздо меньше, чем на Си. Может быть вы испытываете трудности с инструментом, который не освоили? Ну ничего, бывает.

P.S. Когда не нужно ни того, ни другого - пишу на всяких там питонах.

anonymous
()
Ответ на: комментарий от anonymous
: p(nullptr)//вот тут.

У нового нулл - это 0ссылок(пустой) - ты свапаешь, получается у старого 0ссылок(пустой), а нового одна.

2состояния ты эмулируешь через nullptr. Т.е. p == nullptr считает за 0ссылок у T * p, а !nullptr считаешь за за имеющиеся ссылку.

А теперь не юзай nullptr(не трогай данные, которые помещаются в uniq_ptr) и сделай тоже самое(auto_ptr же делает) - т.е. предположим твой uniq_ptr хранит абсалютно любой указатель, причем nullptr валидный указатель.

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

Ты точно так же можешь на 64битах юзать поинтер как рефкаунт, ибо там есть 16левых бит. Это называет эмуляция через хак.

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

У нового нулл - это 0ссылок(пустой)

У какого нового? нулл означает отсутствие объекта, а не ссылок на него. Понимаешь? Объекта нет. Совсем. Откуда у него возьмется счетчик ссылок? Понимаешь? Не для кого тут вести подсчет ссылок - нет никого.

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

2состояния ты эмулируешь через nullptr. Т.е. p == nullptr считает за 0ссылок у T * p, а !nullptr считаешь за за имеющиеся ссылку.

Ни в коем случае. Объект либо существует, либо нет. Счетчик ссылок тут не нужен, поскольку число ссылок ВСЕГДА == 1.

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

Да что ты такой тугой? null означает, что ссылка не ссылается ни на какой объект. И ничего более.

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

Нет никакого флага.

Нет? Ок, 0 - валидный указатель, вперёд делать рабочий unique_ptr.

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

Давай сравним. Возьмем

{
    std::shared_ptr<A> p1(new A);
}

И

{
    std::unique_ptr<A> p2(new A);
}

p1, если объект существует, создаст для объекта специальные метаданные, ассоциированные с ним(объектом, а не ссылкой) и присвоит счетчику ссылок 1. Далее может происходить много разных действий с этими метаданными, это не важно. Когда p1 будет умирать, он проверит, что владеет объектом(он проверяет это точно так же, как и p2, заметь) - это никак не связано с счетчиком ссылок, а потом уже смотрит метаданные. В метаданных он уменьшает число ссылок и если он 0, то удалит объект(кстати говоря, удаление таких объектов в общем случае можно делать отдельно, если пилить свою реализацию RC).

p2 никаких метаданных не создает, никуда ничего не пишет и не сообщает. При своем разрушении он смотрит, указывает ли он на объект и удаляет его. Все. Где тут рефкаунт?

Давай я на сишечке тебе покажу, может понятнее будет?

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

Да уже лет 20 на C++ пишу. Проблем гораздо меньше, чем на Си. Может быть вы испытываете трудности с инструментом, который не освоили? Ну ничего, бывает.

Вы знаете я то-же уже лет 20 на C++ пишу. И проблем с ним то-же нет, потому что я не использую исключения там где не нужно и не проектирую классы с шаблонами где они нафиг не нужны.

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

Ты точно так же можешь на 64битах юзать поинтер как рефкаунт, ибо там есть 16левых бит. Это называет эмуляция через хак.

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

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

У какого нового? нулл означает отсутствие объекта, а не ссылок на него. Понимаешь?

Если его нет, то откуда тут константа:

: p(nullptr). Это запись флага. Это флаг владения, который совмещен с поинтером. Если он совмещен, это не значит, то его нет.

Ещё раз, есть указатель, а есть твоя обвязка. Твоя обвязка должна иметь флаг владения. Твоя обвязка является ссылкой на этот указатель.

Объекта нет. Совсем. Откуда у него возьмется счетчик ссылок? Понимаешь? Не для кого тут вести подсчет ссылок - нет никого.

Как там объекта нет - ты же свапаешь с этим объектом, а если его нет, то чтож ты там свпаешь?

Ты инициализируешь свой объект невалидным значением и считаешь его за «объекта нет». А если у указателя нет невалидного значения? Тебе сказли, что ссылок нет, ты осилил частично скопипастить unique_ptr даже не понимая что там и для чего.

Ещё раз для даунов, твоя обвязка не может трогать данные - т.е. сам поинтер. Не может его юзать для флага «Объекта нет». Ты же юзаешь кастыль - ты берёшь невалидное значение и интерпритируешь его.

Когда ты её трогаешь и записываешь туда NULL - ты юзаешь хак.

Так же, как код возврата из маллока, так же как -1.

Ещё раз для даунов, рефкаунт - это общий флаг владения. А каунт он потому, что владельцев может быть много и состояний у него тоже.

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

А в чем суть чтоб кол-во вызовов free() было равно кол-ву вызовов malloc()? Чем тебя 3 free() не устраивает? Неужели настолько экономишь такты?

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

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

В чем проблема - шаришь указатель.

Ну дак, это тоже будет является отсутвием флага владения/рефкаунта? Его же какбэ не будет - будет один указатель.

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

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

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

Реально ты просто выносишь эту лапшу из класса в другое место, но она непропадает.

Да и к томуже не всегда можно записать какой-то флаг инвалидности в данные.

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

Ещё раз, зачешь чем отличается shared_ptr от unique_ptr? в первом глобальный флаг владения, во втором локальный.

Когда p1 будет умирать, он проверит, что владеет объектом(он проверяет это точно так же, как и p2, заметь) - это никак не связано с счетчиком ссылок, а потом уже смотрит метаданные.

Зачем его что-то проверять, если он может спокойно удалять null? Тыж удалил. Это для делитеров, которые не умеют нулл. В shared_ptr это просто кастыль, в unique_ptr это не только кастыль.

p2 никаких метаданных не создает, никуда ничего не пишет и не сообщает. При своем разрушении он смотрит, указывает ли он на объект и удаляет его. Все. Где тут рефкаунт?

Создаёт, ещё раз глупая лалка:

: p(nullptr)// вот - вот ты их создаёшь.

У тебя поинтер является представлением рефкаунта. nullptr == рефкаунт == 0, когда как !nullptr == рефкаунт == 1, т.е. флаг уникального фладения.

Рефкаунт - это ФЛАГ ВЛАДЕНИЯ, а НЕ СЧЁТЧИК, глупая лалка. Счётчик - это пошаренный флаг. Который считает кол-во владельцев, вернее он не считает - он поддерживает инвариант refcount == 1 == текущий объект - полный владелец. Сам счётчик нахрен не интересен твоему shared_ptr'y.

И да, в твоём шаредптр"е тоже нет счётчика - он ему не нужен. Птр должен знать «являюсь ли я единственным владельцем» - ему нужен лишь флаг полного(мнопольного) владения. А сам рефкаунт - это уже отдельнай байда, которая позволяет поинтеру это знать.

В unique_ptr заложен инвариант - владелец всегда один.

Это позволяет свести рефкаунт к nullptr"y. Это хак. У тебя nullptr считает за я не владею ничем. А !nullptr - я владею всем.

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

Рефкаунт - это ФЛАГ ВЛАДЕНИЯ, а НЕ СЧЁТЧИК, глупая лалка.

А теперь переведи reference _counter_ на русский язык (если ты его знаешь).

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

Создаёт, ещё раз глупая лалка

Нет, не создает. Покажи мне такое создание.

У тебя поинтер является представлением рефкаунта. nullptr == рефкаунт == 0, когда как !nullptr == рефкаунт == 1, т.е. флаг уникального фладения.

Нет. Воображаемый «рефкаунт» для unique_ptr всегда == 1. == 0 не бывает. Приведи пример кода с 0 «рефкаунт» на объект для unique_ptr.

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

Ты совсем не понимаешь разницы? Подсчет ссылок относится к объекту. Потому что мы считаем число ссылок на ОБЪЕКТ. В случае unique_ptr мы не считаем число ссылок, потому что у нас по определению у объекта может быть только 1 ссылка. Не больше и не меньше.

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

Ты с ума сошел? Подсчет ссылок - это когда у нас есть объект и мы считаем число ссылок на него. Так? Когда у нас ссылка nullptr - никакого объекта просто нет. Так? В случае unique_ptr на объект ссылается всегда только одна ссылка. Так? Так зачем подсчитывать что-то, что по определению == 1?

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

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

Аналогично. И как это подтверждает выше вами сказанное?

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

Для подсчета ссылок тебе нужна метаинформация об объекте. Что-то вроде такого(не придирайся к мелочам)

typedef struct shared_node {
    void *data;
    void (*dtor)(void *);
    uint32_t refcount;
} shared_node_t;

inline shared_node_t *
make_shared(void *data, void (*dtor)(void *))
{
    shared_node_t * ptr = malloc(sizeof(node));
    ptr->data = data;
    ptr->dtor = dtor;
    ptr->refcount = 1;
}

inline shared_node_t *
copy_shared(shared_node_t *p)
{
    if (p) ++p->refcount;
    return p;
}

inline void
del_shared(shared_node_t *p)
{
    if (p) --p->refcount;
    if (p && !p->refcount) {
        dtor(p->data);
        free(p);
    }
}

В то время как для уникального владения тебе достаточно, грубо говоря:

inline void *
move_unique(void **p)
{
    void *t = *p;
    *p = 0;
    return t;
}
Какой тут подсчет ссылок? Подсчет ссылок на что?

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

Аналогично. И как это подтверждает выше вами сказанное?

А как НЕ подтверждает?

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

...

У обоих решений имеется общий недостаток: они загромождают код на стороне вызова. Вызывающая сторона должна проверять ошибки немедленно после вызова. К сожалению, об этом легко забыть.

...

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

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

Какие монады?

Ну те самые.

lookup :: Eq a => a -> [(a, b)] -> Maybe b
-- Looks up a value in a key-value association list

myFunc :: Int -> [(String, Int)] -> Maybe Int
myFunc mult assocList = do
    i <- lookup "foo" assocList
    j <- lookup "bar" assocList
    return $ i * mult + j

Here, if the lookup for «foo» fails, the myFunc immediately returns Nothing. Similarly if the lookup for «bar» fails, myFunc immediately returns Nothing. It's only when both lookups succeed does myFunc do any computation. This provides a sort of «error handling».

И никакой лапши из проверок результата каждого «вызова» lookup.

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