LINUX.ORG.RU

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

 


2

4

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

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

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

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

А с людьми работать сложнее всего. Лучше писать программы не для людей, а для ядра например.

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

А пруфы будут?

Ага. Достаточно того что синхронное чтение чего либо с диска запрещено в WinRT под страхом анального изнасилования.

А что ты будешь делать с errno в том же потоке в том же месте?

Это несколько тупых байтиков, а не какой то объект.

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

Для порта в эрланге лучше падать как можно скорее. Такие дела.

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

Кончай хамить, мы не на рынке.

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

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

Достаточно того что синхронное чтение чего либо с диска запрещено в WinRT под страхом анального изнасилования.

Не достаточно. То, что в глубинах нектософта что-то там решили, еще не значит, что это хорошо. Множество исторических примеров говорят скорее об обратном.

что ты будешь делать с errno?
Это несколько тупых байтиков, а не какой то объект.

Тебе не кажется, что твой ответ не согласуется с вопросом?

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

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

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

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

А вот тебе другой пример: Visual Studio 6 (кажется). Часто он из-за какого-то бага (может в нем, а может в каком-то плагине) не вылеатал, а зачем-то обрезал в 0 все файлы, которые в данный момент открыты в редакторе. То есть в редакторе все выглядит хорошо, но на диске данных уже нет, только пустой файл. Лучше бы просто вылетал.

На счет ворда такая же петрушка: лучше пусть вылетит и потеряет последние 10 минут работы (или когда пользователь последний раз сохранялся), чем непонятным образом покорежит весь документ (и не факт, что ctrl+z после этого корректно все восстановит).

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

При разумном использовании не срет.

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

Кстати, для defensive programming исключения тоже лучше кодов ошибок. Чтобы сама программа не падала, в ключевых местах ловятся все исключения (через catch (...) с последующим логгированием, а чтобы логгирование было содержательным используем Boost.Exception), но проблемная операция все-равно будет прервана максимально рано, а не когда повезёт.

Begemoth ★★★★★
()

Просто Qt — это библиотека. Это значит, что она и программа могут быть собраны разными компиляторами, создающими разный код для обработки исключений, этот аспект не стандартизован. Вообще, у C++ нет стандартного ABI, как у C. Разные компиляторы по-разному именуют функции, по-разному формируют объекты в памяти. Поэтому при написании библиотек вообще рекомендуется не использовать исключения, для объектов использовать голые интерфейсы с фабриками, чтобы скрыть реализацию, а в параметрах экспортируемых функций использовать только POD-типы.

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

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

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

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

ranka-lee
()
Последнее исправление: ranka-lee (всего исправлений: 1)
Ответ на: комментарий от ddos3

Когда то давно чтение из памяти тоже считалось почти бесплатным. А кое кто до сих пор так считает.

ranka-lee
()
Последнее исправление: ranka-lee (всего исправлений: 1)
Ответ на: комментарий от ddos3

Рили? Ты же мне расскажешь как откатить только то, что я успел инициализировать и не откатывать то, что не успел?

#include <iostream>
#include <cstdio>

using namespace std;

char * test_alloc(size_t len) {
  char * ptr = new char[len];
  fprintf(stderr, "call: %s(%lu) = %p\n", __FUNCTION__, len, ptr);
  return ptr;
}

void test_dealloc(char * ptr) {
  fprintf(stderr, "call: %s(%p)\n", __FUNCTION__, ptr);
  return delete[] ptr;
}

typedef struct test {
  test() {
    try {
      a = test_alloc(10), b = test_alloc(100000000000000000ul), c = test_alloc(10);
    } catch(std::bad_alloc) { }
  }
  ~test() {
    test_dealloc(a), test_dealloc(b), test_dealloc(c);
  }
  char * a, * b, * c;
} test_t;

int main(int argc, char **argv) {
  test_t t;
  return 0;
}
anonymous
()
Ответ на: комментарий от uuwaan

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

Не может, это же плюсы без ABI

mashina ★★★★★
()

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

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

Не может, это же плюсы без ABI

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

Поэтому, в своей сути, экспорт класса выглядит так: объявляем асбтрактный класс с неперегруженными виртуальными методами (принимающими в качестве параметров POD и указатели на другие интерфейсы), фабрику объявляем как extern «C». Для удобства в интерфейс или рядом можно нарисовать inline обёртки.

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

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

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

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

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

Точнее на том факте, что таблица таблица виртуальных методов разными компиляторами создаётся в едином виде для классов без множественного наследования. Этот факт - требование COM. Вот только GNU/Linux, то тут при чём? Да, даже пофиг на GNU/Linux и прочие POSIX и POSIX-совместимые системы. Интерфейс построенный по требованиям COM ну никак не является современным C++, он гораздо ближе интерфейсам в стиле С, чем современному С++.

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

Ты мне мой пример с RAII выкати, мне твоё «RAII, а не лаша из try-catch» ниочем не говорит. Что ты тут сделаешь? рефкаунт?

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

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

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

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

Ты мне мой пример с RAII выкати

# include <vector>

class Test {
public:
    Test() : a(10), b(100000000000000000ul), c(10) { }
    std::vector<char> a, b, c;
};

int main(int argc, char **argv) {
  Test t;
  return 0;
}
ddos3
()
Ответ на: комментарий от nanoolinux

Причем тут «сырые указатели» - это пример.

Надо так писать конструкторы

Напиши - покажи.

anonymous
()

Тоже самое рекомендует Google и многие другие разработчики. Исключения добавляют больше проблем, чем решают.

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

экспорт класса выглядит так

Я бы экспортировал сишный интерфейс со структурой с указателями на ф-ии. Так ещё более надёжней например.

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

Ты не стесняйся цитаты из Google C++ Style Guide приводить:

On their face, the benefits of using exceptions outweigh the costs, especially in new projects. However, for existing code, the introduction of exceptions has implications on all dependent code. If exceptions can be propagated beyond a new project, it also becomes problematic to integrate the new project into existing exception-free code. Because most existing C++ code at Google is not prepared to deal with exceptions, it is comparatively difficult to adopt new code that generates exceptions.

Выделение моё. Вот только проблема в том, что цитата опровергает твоё высказывание.

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

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

#include <memory>
#include <cstdio>

class Test
{
  std::unique_ptr <char []> a, b, c;

  public:
    Test() :
      a(new char [10]),
      b(new char [100000000000000000ul]),
      c(new char [10]) {}
};

int main(int argc, char **argv)
{
  try {
    Test t;
  } catch (std::bad_alloc &) {
    puts("no memory, neosilyator");
  }

  puts("no memory leaks, neosilyator");
}

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

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

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

Твой игнорирует bad_alloc и сегфолтится при последующей попытке использовать b (если бы это была настоящая программа). Можешь завернуть создание Test t в try/catch и так же проигнорить (при этом ты по крайней мере защищаешься от попыток использовать неинициализированный объект). Или можешь инициализировать пустые вектора и попытаться их ресайзнуть в конструкторе, повторив свой код вместе с багом:

 Test() {
        try {
            a.resize(10);
            b.resize(1000000000000ul);
            c.resize(10);
        } catch (std::bad_alloc&) {
        }
    }

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

Вот только GNU/Linux, то тут при чём?

Ни при чём. Но мы же о Qt говорим, а она под Windows цветёт и пахнет.

Интерфейс построенный по требованиям COM ну никак не является современным C++

Тут уже говорили, что разработка Qt ведётся давно, на тот момент было современно. И плюс это единственный железобетонный способ реализовать бинарно совместимый интерфейс. Разработчики современного C++ занимались иными вещами, даже алгоритм кодирования имён (name mangling) не стандартизован, из-за чего приходится писать extern «C». На низком уровне современный C++ именно таков, так что нет противоречия.

uuwaan ★★
()

Это только внутри Qt, со времен, когда исключения были проблемные

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

Откуда ж столько неосиляторов-то? Откатится то, что было создано(поля, подобъекты базовых классов и пр.) Что тебе еще нужно?

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

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

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

Серьёзное использование смартпоинтеров это признак говна в коде, когда никто не знает что именно в нём происходит

лол.

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

WinRT

Говно ради говна? Нет, спасибо.

Но в чем проблема исключений и асинхронности? Что ты не осилил там?

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

такой важный случай использования RAII из учебников как чтение данных

Это в каких учебника чтение файла делается через RAII?

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

RAII никак не связан с синхронностью/асинхронностью

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

Что ты несешь вообще? Какого конструктора ты собрался ждать?

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

Ну и как это мешает RAII?

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

Что это за лапша? Тебе надо-то чего?

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

Важно то что такой важный случай использования RAII из учебников как чтение данных

Что? Чтение данных через RAII? Завязывай с наркотиками.

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

Исключения добавляют больше проблем, чем решают.

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

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

А вот так. Делаешь ты File file(«pony.jpg») - и у тебя тут будет сидеть ждать пока оно файл откроет. Зато когда кинет исключение то всё, разумеется, красиво так закроется. Иначе толку от RAII?

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