Исключения в C++
От: Шахтер Интернет  
Дата: 23.03.16 14:53
Оценка:
Мне видится, что было бы полезно внести следующие изменения в механизм исключений C++.

Во-первых, добавить новый оператор error.

throw Type(args);

error Type(args);


В отличии от оператора throw, error не прерывает исполнения, а сигнализирует об ошибке.

Блок try/catch должен быть устроен так

try(CatchType obj)
 {
  ....

  error "error 1";

  ....

  throw "error 2";    

  ....
 }


При этом CatchType имеет следующий интерфейс:

class TryCatch
 {
  ....

  public:

   void operator () (const char *str); // для типа const char *

   void operator () (std::exception ex); // для типа std::exception

   ....

   void operator () (); // для оставшихся типов
 };


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

В процессе свёртки стека деструкторы классов принудительно "останавливают" исключения.
Т.е. если в деструкторе произошло исключение, то управление передаётся не на конец try блока, а на конец деструктора.
Тем самым снимается проблема исключений в деструкторах.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re: Исключения в C++
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 23.03.16 15:03
Оценка: +4
Здравствуйте, Шахтер, Вы писали:

Ш>Мне видится, что было бы полезно внести следующие изменения в механизм исключений C++.

Ты можешь написать в комитет и предложить это улучшение.
Ш>В отличии от оператора throw, error не прерывает исполнения, а сигнализирует об ошибке.
Вызывай функцию mynamepsace::error и сигнализируй.
Ш>Блок try/catch должен быть устроен так
Я не понял какую проблему ты хочешь решать? Откуда повились эти мысли о error? Изучил новый язык?
Sic luceat lux!
Re[2]: Исключения в C++
От: Шахтер Интернет  
Дата: 23.03.16 20:36
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Здравствуйте, Шахтер, Вы писали:


K>Я не понял какую проблему ты хочешь решать? Откуда повились эти мысли о error? Изучил новый язык?


В С++ есть проблема обработки кратных ошибок, возникающая при раскрутки стека.
Вот для её удобного решения с поддержкой языка и нужны изменения в механизме исключений.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re: Исключения в C++
От: Erop Россия  
Дата: 23.03.16 20:37
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Мне видится, что было бы полезно внести следующие изменения в механизм исключений C++.

1) Зачем запутывать то, что и так запутанно по самое не хочу, ещё дальше?
2) Зачем в деструкторах нужны исключения?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Исключения в C++
От: Шахтер Интернет  
Дата: 24.03.16 01:06
Оценка: +1
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Шахтер, Вы писали:


Ш>>Мне видится, что было бы полезно внести следующие изменения в механизм исключений C++.

E>1) Зачем запутывать то, что и так запутанно по самое не хочу, ещё дальше?

Не запутывать, а совершенствовать.

E>2) Зачем в деструкторах нужны исключения?


Класс File, например. Исключение сигнализируют об ошибке. Есть масса естественных ситуаций, когда ошибки возникают при завершающих действиях.

class File : NoCopy
 {
   FileHandle handle;

  private:

   static ErrorType Open(FileHandle &handle,const char *name);

   static ErrorType Close(FileHandle handle);

  public:

   explicit File(const char *name)
    {
     if( ErrorType e=Open(handle,name) ) throw e;
    }

   ~File() noexcept(false)
    {
     if( ErrorType e=Close(handle) ) throw e;
    }
 };

struct CatchType
 {
  void operator() (ErrorType e)
   {
    // печатаем сообщение об ошибке, например
   }
 };

....

try( CatchType catch_obj )
 {
  File file1("name1");
  File file2("name2");

  ....
 
 }

// Дошли до конца блока, сработал деструктор file2, выбросил исключение. При этом был вызван оператор () у catch.
// Дальше пошла раскрутка стека. Сработал деструктор file1. Тоже выбросил исключение. Опять был вызван оператор () у catch. 
// Второе исключение, однако, передало управление на конец деструктора. Т.е. раскрутка стека продолжилась. В конце концов, управление передано на конец try блока.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[3]: Исключения в C++
От: Erop Россия  
Дата: 24.03.16 04:45
Оценка:
Здравствуйте, Шахтер, Вы писали:


Ш>Класс File, например. Исключение сигнализируют об ошибке. Есть масса естественных ситуаций, когда ошибки возникают при завершающих действиях.


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

Вот представь себе, что твой File в качестве трёх полей агрегирован в какой-то класс. Мы разрушаем экземпляр этого класса, и во время разрушения второго File получаем исключение "диск полный". Тут, по идее, пользователю надо дать шанс почистить диск и повторить запись. Как делаем?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Исключения в C++
От: Evgeny.Panasyuk Россия  
Дата: 24.03.16 05:09
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>В процессе свёртки стека деструкторы классов принудительно "останавливают" исключения.

Ш>Т.е. если в деструкторе произошло исключение, то управление передаётся не на конец try блока, а на конец деструктора.
Ш>Тем самым снимается проблема исключений в деструкторах.

В качестве эксперимента можно подобное реализовать на базе unwinding_indicator
Автор: Evgeny.Panasyuk
Дата: 01.10.12
.
Re[4]: Исключения в C++
От: Evgeny.Panasyuk Россия  
Дата: 24.03.16 05:25
Оценка:
Здравствуйте, Erop, Вы писали:

E>Вот представь себе, что твой File в качестве трёх полей агрегирован в какой-то класс. Мы разрушаем экземпляр этого класса, и во время разрушения второго File получаем исключение "диск полный". Тут, по идее, пользователю надо дать шанс почистить диск и повторить запись. Как делаем?


Через TLS-стэк обработчиков или например через корутины/потоки.
В принципе вот такой синтаксис реализуется уже сейчас:
{
    // near stack root
    SPECIAL_TRY
    {
        write_file();
    }
    SPECIAL_CATCH(not_enough_space x)
    {
        if(try_to_free_space(x.size()))
            return continue_execution;
        else
            return throw_exception;
    };
}

{
    // deep inside stack
    raise(not_enough_space{size}); // may throw or continue
    // at this point we have enough space
}
Re[5]: Исключения в C++
От: Erop Россия  
Дата: 24.03.16 05:37
Оценка: +3
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Через TLS-стэк обработчиков или например через корутины/потоки.

EP>В принципе вот такой синтаксис реализуется уже сейчас:

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

И всё ради чего?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Исключения в C++
От: Erop Россия  
Дата: 24.03.16 05:39
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>В С++ есть проблема обработки кратных ошибок, возникающая при раскрутки стека.

Ш>Вот для её удобного решения с поддержкой языка и нужны изменения в механизме исключений.

Это, как минимум, нетестируемо... Тебе надо будет покрывать тестами не только все ошибки, но и все их сочетания...
Или ты надеешься обрабатывать ошибки без сайд-эффектов?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Исключения в C++
От: Erop Россия  
Дата: 24.03.16 05:41
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>В качестве эксперимента можно подобное реализовать на базе unwinding_indicator
Автор: Evgeny.Panasyuk
Дата: 01.10.12
.


Проблема не том, как реализовать, а в том, что реализовывать, что бы было не хуже, чем сейчас, а лучше...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Исключения в C++
От: _niko_ Россия  
Дата: 24.03.16 06:32
Оценка: -1
Здравствуйте, Шахтер, Вы писали:

Ш>Класс File, например. Исключение сигнализируют об ошибке. Есть масса естественных ситуаций, когда ошибки возникают при завершающих действиях.


Если:
— при закрытии файла (file.close();) можно словить исключение;
— объект file может быть разрушен при раскрутке стука по исключению
... то сделай так чтобы файл не закрывался при разрушении объекта file — все, проблема решина, т.е. вызов file.close(); в деструкторе file по факту ничего уже закрывать не будет и ошибок не произойдет.

Считаем что закрытие файла при разрушении объекта file (раз в этом случае может сгенирироваться исключение) уже есть не совсем нормальное поведение. И если тут происходит еще что то не нормальное ну значит так таму и быть вылетом из приложения по terminate — все логично.

Изночально нужно писать код так чтобы всегда была альтернатива пробрасыванию исключения из деструктора.
А для перекрытия одного исключения другим как раз таки с C++11 у нас появились вложенные исключения.
Re[2]: Исключения в C++
От: enji  
Дата: 24.03.16 06:41
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Я не понял какую проблему ты хочешь решать? Откуда повились эти мысли о error? Изучил новый язык?


У меня периодически бывают случаи, когда в разных функциях есть одинаковые блоки catch. И счас эта задача нормально не решается — или макры или запоминание и перевыброс текущего исключения (что по идее не быстро)
Re[6]: Исключения в C++
От: Evgeny.Panasyuk Россия  
Дата: 24.03.16 07:10
Оценка:
Здравствуйте, Erop, Вы писали:

EP>>Через TLS-стэк обработчиков или например через корутины/потоки.

EP>>В принципе вот такой синтаксис реализуется уже сейчас:
E>Ну это же всё дико сложно работает, и отлаживать трудно и тестами покрывать...

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

E>И всё ради чего?


Ты же задачу такую поставил, или нет? То есть нужно обработать и исправить ошибку где-то выше по логическому стэку компонентов, там где есть необходимая информация и полномочия, а потом продолжить на исходном низком уровне, так?
Сложность-то она в самой задаче, а не в решении.
Re[3]: Исключения в C++
От: Шахтер Интернет  
Дата: 24.03.16 10:14
Оценка:
Здравствуйте, enji, Вы писали:

E>Здравствуйте, Kernan, Вы писали:


K>>Я не понял какую проблему ты хочешь решать? Откуда повились эти мысли о error? Изучил новый язык?


E>У меня периодически бывают случаи, когда в разных функциях есть одинаковые блоки catch. И счас эта задача нормально не решается — или макры или запоминание и перевыброс текущего исключения (что по идее не быстро)


Да, и эта проблема тоже решается.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[2]: Исключения в C++
От: Шахтер Интернет  
Дата: 24.03.16 10:18
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, Шахтер, Вы писали:


Ш>>В процессе свёртки стека деструкторы классов принудительно "останавливают" исключения.

Ш>>Т.е. если в деструкторе произошло исключение, то управление передаётся не на конец try блока, а на конец деструктора.
Ш>>Тем самым снимается проблема исключений в деструкторах.

EP>В качестве эксперимента можно подобное реализовать на базе unwinding_indicator
Автор: Evgeny.Panasyuk
Дата: 01.10.12
.


Можно, да. Но требует дисциплины программирования. Хочется нормальную поддержку на уровне языка.
И код станет красивше...
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[4]: Исключения в C++
От: Шахтер Интернет  
Дата: 24.03.16 10:23
Оценка: -1
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Шахтер, Вы писали:



Ш>>Класс File, например. Исключение сигнализируют об ошибке. Есть масса естественных ситуаций, когда ошибки возникают при завершающих действиях.


E>Проблема не в том, что ошибки возникают, а в том, что не понятно как их обрабатывать. Отменить-то деструктор мы обычно не можем?


E>Вот представь себе, что твой File в качестве трёх полей агрегирован в какой-то класс. Мы разрушаем экземпляр этого класса, и во время разрушения второго File получаем исключение "диск полный". Тут, по идее, пользователю надо дать шанс почистить диск и повторить запись. Как делаем?


Нет, исключения остаются без возобновления.
А твой случай нужно разруливать не на исключениях, а на продолжениях.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[7]: Исключения в C++
От: Erop Россия  
Дата: 24.03.16 10:47
Оценка: +3
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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

EP>Сложность-то она в самой задаче, а не в решении.

Ну вот смотри, мы пишем ТРИ файла, флушим, получаем "места нет", и решаем, то надо спросить пользователя что делать. Пользователь говорит: "пиши док на другой диск". И как это случится?

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

А как спрашивать вышестоящий код, что делать, через исключения или через колбэки -- не суть.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Исключения в C++
От: Erop Россия  
Дата: 24.03.16 11:01
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>А твой случай нужно разруливать не на исключениях, а на продолжениях.


Вот я и спрашиваю, зачем всё так усложнять?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Исключения в C++
От: smeeld  
Дата: 24.03.16 11:19
Оценка:
Здравствуйте, Шахтер, Вы писали:


Ш>Во-первых, добавить новый оператор error.


Вообще говоря, если исключения в С++ такие, какие они есть, то значит это кому-то нужно. Не нужно пытаться что-то изменить, всё равно проигнорируют. Например, в Lisp-ах исключения более функциональны и более оптимально реализованы, это появилось задолго до появления С++, и в С++ запросто могли взять исключения по образу и подобию Lisp-овых, но вместо этого нагородили что-то явно более уродливое, непродуманное и неоптимальное. Значит это кому-то нужно.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.