ARM: C++ exceptions
От: Аноним  
Дата: 26.08.07 15:33
Оценка:
Тема использовать или не использовать много раз обсуждалась,
но теперь столкнулся с ней напрямую, и не знаю что делать.

Есть ARM и 64 Мб, надо выбрать использовать или не использовать
исключения, до написания основного кода,

какие бы вы выбрали тесты для этого будь у вас железка и кроскомпилятор
gcc 4.x для этого?
Re: ARM: C++ exceptions
От: Uzumaki Naruto Ниоткуда  
Дата: 26.08.07 17:47
Оценка:
Использовать или не использовать — зависит от типа ARM. Я по жизни не люблю использовать исключения, по этому не стал бы их использовать в данном случае.

Re: ARM: C++ exceptions
От: Шахтер Интернет  
Дата: 26.08.07 19:25
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Тема использовать или не использовать много раз обсуждалась,

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

А>Есть ARM и 64 Мб, надо выбрать использовать или не использовать

А>исключения, до написания основного кода,

А>какие бы вы выбрали тесты для этого будь у вас железка и кроскомпилятор

А>gcc 4.x для этого?

Я использую исключения. Как раз на ARM е c 64 Мб и gcc 4.x.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[2]: ARM: C++ exceptions
От: Awaken Украина  
Дата: 26.08.07 19:55
Оценка:
UN>Использовать или не использовать — зависит от типа ARM. Я по жизни не люблю использовать исключения, по этому не стал бы их использовать в данном >случае.

нмв неиспользование исключений приводит к коду в стиле "Си с классами". фактически ты лишаешься RAII
Re[3]: ARM: C++ exceptions
От: remark Россия http://www.1024cores.net/
Дата: 26.08.07 20:55
Оценка:
Здравствуйте, Awaken, Вы писали:

UN>>Использовать или не использовать — зависит от типа ARM. Я по жизни не люблю использовать исключения, по этому не стал бы их использовать в данном >случае.


A>нмв неиспользование исключений приводит к коду в стиле "Си с классами". фактически ты лишаешься RAII


А так же конструкторов, операторов и функций с удобной сигнатурой


1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: ARM: C++ exceptions
От: Awaken Украина  
Дата: 26.08.07 21:19
Оценка:
Ш>Я использую исключения. Как раз на ARM е c 64 Мб и gcc 4.x.
а что за платформа и приложение?
Re[2]: ARM: C++ exceptions
От: Alexander Pazdnikov  
Дата: 27.08.07 04:13
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Я использую исключения. Как раз на ARM е c 64 Мб и gcc 4.x.


Идентично.
Re: ARM: C++ exceptions
От: dip_2000 Россия  
Дата: 27.08.07 04:14
Оценка:
Использую исключения. Платформа ARM. Win Mobile 5, 6. В том числе в достаточно критических местах. Проблемм не замечал, хотя и тестов скорости, сравнительных, с ситуацией "без исключений", не проводил. Компилятор родной VS 2005 SP1
Re[3]: ARM: C++ exceptions
От: Erop Россия  
Дата: 27.08.07 09:00
Оценка:
Здравствуйте, Awaken, Вы писали:

A>нмв неиспользование исключений приводит к коду в стиле "Си с классами". фактически ты лишаешься RAII


А зачем?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: ARM: C++ exceptions
От: korzh.pavel Россия  
Дата: 27.08.07 09:20
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Тема использовать или не использовать много раз обсуждалась,

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

А>Есть ARM и 64 Мб, надо выбрать использовать или не использовать

А>исключения, до написания основного кода,

А>какие бы вы выбрали тесты для этого будь у вас железка и кроскомпилятор

А>gcc 4.x для этого?

Может здесь что нибудь найдёшь: Technical Report on C++ Performance
Re[3]: ARM: C++ exceptions
От: Шахтер Интернет  
Дата: 29.08.07 02:45
Оценка:
Здравствуйте, Awaken, Вы писали:

Ш>>Я использую исключения. Как раз на ARM е c 64 Мб и gcc 4.x.

A>а что за платформа и приложение?

Это не приложение. Я делал экспериментальное RT ядро для ixp465. Компилятор -- gcc-4.1.1 с подправленной RTL (в частности, для того чтобы можно было использовать C++ для обработки прерываний).
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[4]: ARM: C++ exceptions
От: alexeiz  
Дата: 29.08.07 06:02
Оценка:
Здравствуйте, Erop, Вы писали:

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


A>>нмв неиспользование исключений приводит к коду в стиле "Си с классами". фактически ты лишаешься RAII


E>А зачем?


В смысле, зачем? Ты считаешь, что RAII — ненужная, бесполезная вещь? Объясни.
Re[5]: ARM: C++ exceptions
От: Erop Россия  
Дата: 29.08.07 06:51
Оценка:
Здравствуйте, alexeiz, Вы писали:

E>>А зачем?

A>В смысле, зачем? Ты считаешь, что RAII — ненужная, бесполезная вещь? Объясни.
Зачем лишаться RAII если не использовать исключения?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: ARM: C++ exceptions
От: alexeiz  
Дата: 29.08.07 07:06
Оценка:
Здравствуйте, Erop, Вы писали:

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


E>>>А зачем?

A>>В смысле, зачем? Ты считаешь, что RAII — ненужная, бесполезная вещь? Объясни.
E>Зачем лишаться RAII если не использовать исключения?

Захват ресурсов происходит в конструкторе (= resource aquisition is initialization). Без исключений ты не можешь проделать это в конструкторе по очевидным причинам.
Re[7]: ARM: C++ exceptions
От: Sergey Россия  
Дата: 29.08.07 08:06
Оценка:
> E>>>А зачем?
> A>>В смысле, зачем? Ты считаешь, что RAII — ненужная, бесполезная вещь? Объясни.
> E>Зачем лишаться RAII если не использовать исключения?
>
> Захват ресурсов происходит в конструкторе (= resource aquisition is initialization). Без исключений ты не можешь проделать это в конструкторе по очевидным причинам.

Да ну. Проверок просто вставлять придется кучу, и все.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[8]: ARM: C++ exceptions
От: alexeiz  
Дата: 29.08.07 08:43
Оценка:
Здравствуйте, Sergey, Вы писали:

>> E>>>А зачем?

>> A>>В смысле, зачем? Ты считаешь, что RAII — ненужная, бесполезная вещь? Объясни.
>> E>Зачем лишаться RAII если не использовать исключения?
>>
>> Захват ресурсов происходит в конструкторе (= resource aquisition is initialization). Без исключений ты не можешь проделать это в конструкторе по очевидным причинам.

S>Да ну. Проверок просто вставлять придется кучу, и все.


В конструкторе? А иначе это не RAII.
Re[7]: ARM: C++ exceptions
От: Erop Россия  
Дата: 29.08.07 08:55
Оценка:
Здравствуйте, alexeiz, Вы писали:

A>Захват ресурсов происходит в конструкторе (= resource aquisition is initialization). Без исключений ты не можешь проделать это в конструкторе по очевидным причинам.


А что помешает?
Ну будет у CFile метод bool IsOpend() const, и тебе после открытя файла прийдётся проверять получилось ли.
Ну так и без RAII пришлось бы. А вот зарыть файл в деструкторе тебе ничего не помешает...

Хуже с операторами. Прийдётся какие-то невалидные состояния объектов заводить. Ну либо подход, который нравится мне использовать
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[8]: ARM: C++ exceptions
От: alexeiz  
Дата: 29.08.07 09:34
Оценка:
Здравствуйте, Erop, Вы писали:

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


A>>Захват ресурсов происходит в конструкторе (= resource aquisition is initialization). Без исключений ты не можешь проделать это в конструкторе по очевидным причинам.


E>А что помешает?

E>Ну будет у CFile метод bool IsOpend() const, и тебе после открытя файла прийдётся проверять получилось ли.

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

E>Ну так и без RAII пришлось бы. А вот зарыть файл в деструкторе тебе ничего не помешает...


E>Хуже с операторами. Прийдётся какие-то невалидные состояния объектов заводить. Ну либо подход, который нравится мне использовать


Какой это подход?
Re[8]: ARM: C++ exceptions
От: Awaken Украина  
Дата: 29.08.07 09:59
Оценка:
E>Хуже с операторами. Прийдётся какие-то невалидные состояния объектов заводить. Ну либо подход, который нравится мне использовать

поделись секретом
Re[8]: ARM: C++ exceptions
От: Awaken Украина  
Дата: 29.08.07 10:22
Оценка:
>> Захват ресурсов происходит в конструкторе (= resource aquisition is initialization). Без исключений ты не можешь проделать это в >конструкторе по очевидным причинам.
S>Да ну. Проверок просто вставлять придется кучу, и все.

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


class Composite
{
   A a;
   B b:
public:
   Composite(x, y):a(x),b(y) 
};


просто инициализируем и не паримся. если объект А проинициализирован, а B кинул исключение, А будет уничтожен корректно
без RAII:


class Composite
{
   A* a;
   B* b:
public:
   Composite() {} // нельзя проинициализировать A и B здесь
   bool Initialize(x, y)
   {
      a = new A(x);
      if(a == NULL)
         return false;
      b = new B(y);
      if(b == NULL)
      {
          delete b;
          return false
      }
      // если таких как a и b с десяток, код здесь будет полный ахтунг
      // в худшем варианте придется еще делать
      // a = new A(x)
      // rt = a->Initialize(params);
      // if(rt != ERROR) ....
   }
};


можно конечно намутить с временным сохранением успешно созданых объектов
class Composite
{
   A* a;
   B* b;
   // ...
   std::list<boost::any> created;
public:
   Composite() {} // нельзя проинициализировать A и B здесь
   bool Initialize(x, y)
   {
      a = new A();
      ret = a->Initialize(x);
      if(ret == success)
         created.push_back( a );
      else
         goto error_exit;
     
      b = new B();
      ret = b->Initialize(y);
      if(ret == success)
          created.push_back(b);
      else
         goto error_exit;

      // и так много раз 
ok:   return true;
error_exit:
      // удаляем все что в created
      return false;
   }
};


желающие могут поупражнятся без goto лень было
Re[9]: ARM: C++ exceptions
От: Sergey Россия  
Дата: 29.08.07 10:38
Оценка:
>>> E>>>А зачем?
>>> A>>В смысле, зачем? Ты считаешь, что RAII — ненужная, бесполезная вещь? Объясни.
>>> E>Зачем лишаться RAII если не использовать исключения?
>>>
>>> Захват ресурсов происходит в конструкторе (= resource aquisition is initialization). Без исключений ты не можешь проделать это в конструкторе по очевидным причинам.
>
> S>Да ну. Проверок просто вставлять придется кучу, и все.
>
> В конструкторе? А иначе это не RAII.

В деструкторе, чтобы незахваченные ресурсы не освобождать. И после создания объекта придется проверять, удалось ли ему захватить что надо или нет.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[9]: ARM: C++ exceptions
От: Erop Россия  
Дата: 29.08.07 16:33
Оценка:
Здравствуйте, Awaken, Вы писали:

E>>Хуже с операторами. Прийдётся какие-то невалидные состояния объектов заводить. Ну либо подход, который нравится мне использовать


A>поделись секретом


Например, тут внизу
Автор: Erop
Дата: 24.08.07

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

Ну а если что-то поломалось, то либо по длинному goto уходим на откат запроса, либо сэвимся и перезапускаемся (если на платформе это просто и быстро)
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: ARM: C++ exceptions
От: Awaken Украина  
Дата: 29.08.07 17:21
Оценка:
E>Соответсвенно где-то на уровне запросов делается регистрилка всего критического (файлов, например), а запрос обрабатывается на отдельно аллокаторе. >Соответсвенно, если всё удачно, то результат спасаем, неосвобождённые ещё критические ресурсы освобождаем, а промежуточные данные грохаем (можно прямо >всем аллокатором)

фактически это типа thread-local аллокатор.
Re[10]: ARM: C++ exceptions
От: remark Россия http://www.1024cores.net/
Дата: 29.08.07 17:24
Оценка:
Здравствуйте, Erop, Вы писали:

E>Вкраце схема предполагает, что исключения происходят редко. Типа в ошибочных ситуациях. Например в конце памяти.

E>Соответсвенно где-то на уровне запросов делается регистрилка всего критического (файлов, например), а запрос обрабатывается на отдельно аллокаторе. Соответсвенно, если всё удачно, то результат спасаем, неосвобождённые ещё критические ресурсы освобождаем, а промежуточные данные грохаем (можно прямо всем аллокатором)

Дааа. На что только люди не идут, дабы только не использовать исключения
[и оставаться по инструментальным средствам на уровне 60-ых годов прошлого века ]


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[11]: ARM: C++ exceptions
От: Awaken Украина  
Дата: 29.08.07 17:26
Оценка:
R>Дааа. На что только люди не идут, дабы только не использовать исключения
мы ж не знаем че он пишет... может ембеддед хрень какую-нибудь. или риалтайм
бывают ситуации когда такие извращения необходимы
Re[11]: ARM: C++ exceptions
От: Erop Россия  
Дата: 29.08.07 22:00
Оценка:
Здравствуйте, Awaken, Вы писали:

A>фактически это типа thread-local аллокатор.

Ну такой подход позволяет сделать и это. Но он позволяет больше!
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[11]: ARM: C++ exceptions
От: Erop Россия  
Дата: 29.08.07 22:14
Оценка:
Здравствуйте, remark, Вы писали:

R>Дааа. На что только люди не идут, дабы только не использовать исключения

R>[и оставаться по инструментальным средствам на уровне 60-ых годов прошлого века ]

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

На самомо деле не всё так плохо. Смотри. Есть thread-local указатель на текущий контекст запроса, где можно регить и разрегивать критические ресурсы. Соответсвенно их захват и освобождение происходит вполне так себе в рамках RAII, только кроме захвата производится ещё и регистрация ресурса в запросе.

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

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

А моя альтернатива проще и быстрее.
Ты всё это строишь на отдельном аллокаторе (который, если память реально отдавать надо редко, может ещё и быть очень быстрым и thread-local к тому же), потом копируешь полученный в результате кроссворд на другой аллокатор, а потом всё это прекрасное хозяйство просто выбрасываешь, а память освобождаешь прямо всем аллокатором. Совсем не тратя время на разрушение списков и счётчики умных указателей.

Этакий "GC для бедных"
Но есть две засады.
Засада 1.
Захват памяти, аллокированной на временном аллокаторе, статическими или просто долгоживущими объектами. Для решения этой проблемы желательна поддержка со стороны библиотеки контейнеров. Например, удобно пользоваться контейнерами, которые помнят, на каком аллокаторе они были созданы, и пользуются только им.

Засада 2.
Захват объектами, созданными на временном аллокаторе, каких-то критических ресурсов (память вне временного аллокатора, открытые файлы, временные файлы, объекты GDI и т. д.)
Эта засада решается описанной мной выше схемой с регистрилками.



Ну а что касается "инструментальных средств 60-х годов прошлого века", то это ты наверное про С?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[9]: ARM: C++ exceptions
От: Erop Россия  
Дата: 29.08.07 22:21
Оценка:
Здравствуйте, Awaken, Вы писали:

A>вот например такой случай: объект типа "композит", содержащий внутренние объекты.


А какие проблемы?

"Одинокий объект":
CFile myFile( getMyFileName() );
if( !myFile.IsOpened() )
    return ErrorStatus;


"Объект-композит":
class CMyFileWithLog {
public:
    CMyFileWithLog( std::string myFileName ) : file(myFileName ), logFile( myFileName + ".log" ) {}
    bool IsOpend() { return file.IsOpend() && logFile.IsOpend(); }
private:
    CFile file;
    CFile logFile;    
};
//-----------------------------
CMyFileWithLog myFile( getMyFileName() );
if( !myFile.IsOpened() )
    return ErrorStatus;
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: ARM: C++ exceptions
От: Шахтер Интернет  
Дата: 29.08.07 22:32
Оценка:
Здравствуйте, Awaken, Вы писали:

UN>>Использовать или не использовать — зависит от типа ARM. Я по жизни не люблю использовать исключения, по этому не стал бы их использовать в данном >случае.


A>нмв неиспользование исключений приводит к коду в стиле "Си с классами". фактически ты лишаешься RAII


RAII и исключения не зависят друг от друга.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[7]: ARM: C++ exceptions
От: Шахтер Интернет  
Дата: 29.08.07 22:32
Оценка:
Здравствуйте, alexeiz, Вы писали:

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


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


E>>>>А зачем?

A>>>В смысле, зачем? Ты считаешь, что RAII — ненужная, бесполезная вещь? Объясни.
E>>Зачем лишаться RAII если не использовать исключения?

A>Захват ресурсов происходит в конструкторе (= resource aquisition is initialization). Без исключений ты не можешь проделать это в конструкторе по очевидным причинам.


Бред.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[12]: ARM: C++ exceptions
От: remark Россия http://www.1024cores.net/
Дата: 30.08.07 00:28
Оценка:
Здравствуйте, Erop, Вы писали:

E>Соответсвенно, если ты всё пишешь "честно" и зовёшь все деструкторы, то никаких проблем. Вс работает "и так". Ну а если ты таки что-то как-то грохаешь "всем скопом", то у тебя в запроме остаются зарегистрированные данные для освобождения критических ресурсов.


А зачем 2 механизма?
Каждый из них по отдельности может справляться.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[10]: ARM: C++ exceptions
От: alexeiz  
Дата: 30.08.07 05:26
Оценка:
Здравствуйте, Erop, Вы писали:

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


A>>вот например такой случай: объект типа "композит", содержащий внутренние объекты.


E>А какие проблемы?


E>"Одинокий объект":

E>
CFile myFile( getMyFileName() );
E>if( !myFile.IsOpened() )
E>    return ErrorStatus;


E>"Объект-композит":
class CMyFileWithLog {
E>public:
E>    CMyFileWithLog( std::string myFileName ) : file(myFileName ), logFile( myFileName + ".log" ) {}
E>    bool IsOpend() { return file.IsOpend() && logFile.IsOpend(); }
E>private:
E>    CFile file;
E>    CFile logFile;    
E>};
E>//-----------------------------
E>CMyFileWithLog myFile( getMyFileName() );
E>if( !myFile.IsOpened() )
E>    return ErrorStatus;


myFileName + ".log"

Здесь создается новая временная string. Допустим, не хватило памяти. Тогда что? Все равно файл попытается создаться. Да и вообще в copy-constructor'е myFileName уже может все свалиться. Тогда получится целая цепочка невалидных объектов. Соответственно возникает несколько проблем:

* Как мне узнать в конце концов первоначальную причину, по которой все свалилось, если невалидные объекты накапливаются как снежный ком?
* Перед каждой операцией с объектом нужно проверять его валидность. Вот мне в функцию пришел объект по константной ссылке, но я не могу быть уверен, что он валидный, потому что это мог быть времменный объект, который не смог создаться.
* Нет уверенности, что в какой-то точке программы все нужные объекты будут валидными.

Что-то мне это не нравится. Сдается, что здесь много подводных камней просто из-за того, что ожидаешь, что это будет работать как в RAII, и подловишься в один прекрасный момент на невалидном объекте.
Re[8]: ARM: C++ exceptions
От: alexeiz  
Дата: 30.08.07 05:27
Оценка:
Здравствуйте, Шахтер, Вы писали:

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


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


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


E>>>>>А зачем?

A>>>>В смысле, зачем? Ты считаешь, что RAII — ненужная, бесполезная вещь? Объясни.
E>>>Зачем лишаться RAII если не использовать исключения?

A>>Захват ресурсов происходит в конструкторе (= resource aquisition is initialization). Без исключений ты не можешь проделать это в конструкторе по очевидным причинам.


Ш>Бред.


Когда нечего сказать, начинаешь хамить?
Re[11]: ARM: C++ exceptions & RAII
От: Erop Россия  
Дата: 30.08.07 06:08
Оценка:
Здравствуйте, alexeiz, Вы писали:

A>Здесь создается новая временная string. Допустим, не хватило памяти. Тогда что? Все равно файл попытается создаться. Да и вообще в copy-constructor'е myFileName уже может все свалиться. Тогда получится целая цепочка невалидных объектов. Соответственно возникает несколько проблем:


Вообще-то это проблемы не RAII, а операторов и обработки ошибок.
Можно сделать, например, так.
1) Аллокировать подушку.
2) В случае конца памяти взвести флаг, что типа память кончилась, а подушку освободить.
3) Завести регистрилку ошибок. Куда их добавлять по мере появления, а потом всем кагалом обрабатывать, если что.
4) Когда обрабатываем ошибки -- тупо смотрим была ли использована подушка. Если была, пробуем аллокировать её заново. Если не можем -- то авост.
Можно иметь ещё одну "запасную" подушку, чтобы суметь сохранить работу пользователя и перезапуститься.

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

A>* Как мне узнать в конце концов первоначальную причину, по которой все свалилось, если невалидные объекты накапливаются как снежный ком?

A>* Перед каждой операцией с объектом нужно проверять его валидность. Вот мне в функцию пришел объект по константной ссылке, но я не могу быть уверен, что он валидный, потому что это мог быть времменный объект, который не смог создаться.
A>* Нет уверенности, что в какой-то точке программы все нужные объекты будут валидными.

смотри выше.

A>Что-то мне это не нравится. Сдается, что здесь много подводных камней просто из-за того, что ожидаешь, что это будет работать как в RAII, и подловишься в один прекрасный момент на невалидном объекте.


Всё-таки главная фишка RAII -- это освобождение ресурсов в деструкторе. Она остаётся доступной.
Мало того, остаётся доступным и захват объектов в конструкторах, если программа написана так, что провал захвата -- это ошибка. То есть написать так:
bool access_file( std::string name ) 
{
    try {
        CFile file( name );
    } catch( ... ) {
        return false;
    }
    return true;
}
не получится.

А написать так:
CEssentialData ReadMyApplicationsEssentialData()
{
    CEssentialDataPodArchive tmp;
    CFile file( GetReadMyApplicationsEssentialDataFileName() );
    file.ReadRecord( tmp );
    return CEssentialData( tmp );
}
Вполне получится.

И даже так, тоже получится:
bool access_file( std::string name ) 
{
    CFile file;
    return file.Open( name );
}



Так что кое-каrие ограничения в RAII конечно будут, но говорить о безусловном отказе, ИМХО, слишком круто.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[13]: ARM: C++ exceptions
От: Erop Россия  
Дата: 30.08.07 06:12
Оценка:
Здравствуйте, remark, Вы писали:

R>А зачем 2 механизма?

R>Каждый из них по отдельности может справляться.

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

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

Так что один и тот же код в результате может работать и на платфороме с исключениями и на платформе без исключений и с такой политикой аллокации и с другой...
Изменения надо вносить в довольно незначительном перечне мест...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[12]: ARM: C++ exceptions & RAII
От: alexeiz  
Дата: 30.08.07 07:27
Оценка:
Здравствуйте, Erop, Вы писали:

E>смотри выше.


Я таким, как выше, страдать не буду. Лучше отказаться от конструкторов как таковых (кроме инициализирующих объект по-умолчанию). По крайней мере я видел и знаю, что без конструкторов и с Initialize() методом, можно писать надежный код. Примеров кода в таком стиле, как ты рассказываешь, я не встречал. Поэтому он у меня вызывает большие сомнения. Необходимость таких эзотерических методов обработки ошибок рассеять сомнения никак не помогает. Покажи мне пример реального кода. Мне очень интересно посмотреть, как это работает.

A>>Что-то мне это не нравится. Сдается, что здесь много подводных камней просто из-за того, что ожидаешь, что это будет работать как в RAII, и подловишься в один прекрасный момент на невалидном объекте.


E>Всё-таки главная фишка RAII -- это освобождение ресурсов в деструкторе. Она остаётся доступной.


Освобождение в деструкторе — это не главная фишка RAII. Это вообще не фишка RAII. Этот принцип был в языке задолго до того, как появилась идея RAII. Главная фишка — захват в конструкторе и гарантия, что если это не получилось, то объект не создастся, и таким образом не будет невалидных объектов.

E>Мало того, остаётся доступным и захват объектов в конструкторах, если программа написана так, что провал захвата -- это ошибка. То есть написать так:

E>
E>bool access_file( std::string name ) 
E>{
E>    try {
E>        CFile file( name );
E>    } catch( ... ) {
E>        return false;
E>    }
E>    return true;
E>}
не получится.


E>А написать так:
E>CEssentialData ReadMyApplicationsEssentialData()
E>{
E>    CEssentialDataPodArchive tmp;
E>    CFile file( GetReadMyApplicationsEssentialDataFileName() );
E>    file.ReadRecord( tmp );
E>    return CEssentialData( tmp );
E>}
Вполне получится.


Как же! Если честно, игнорирование всех исключительных ситуаций в этом коде приводит меня в ужас. Если даже коды ошибок куда-то и складываются, почему ты думаешь, что можно спокойно продолжать дальше работать? Объект file может и не создасться, но ты все равно вызываешь у него ReadRecord(). Какой это имеет смысл, и к чему это может привести? (Ну, допустим, к чему это может привести, я догадываюсь)

E>И даже так, тоже получится:
E>bool access_file( std::string name ) 
E>{
E>    CFile file;
E>    return file.Open( name );
E>}



E>Так что кое-каrие ограничения в RAII конечно будут, но говорить о безусловном отказе, ИМХО, слишком круто.


Отказ от RAII — это невозможность иметь конструкторов, гарантированно создающих валидный объект. Как я сказал и раньше, ты такую ситуацию все еще называешь RAII. Я — нет.
Re: ARM: C++ exceptions
От: Аноним  
Дата: 30.08.07 13:41
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Тема использовать или не использовать много раз обсуждалась,

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

А>Есть ARM и 64 Мб, надо выбрать использовать или не использовать

А>исключения, до написания основного кода,

А>какие бы вы выбрали тесты для этого будь у вас железка и кроскомпилятор

А>gcc 4.x для этого?

Провел первое тестирование, результаты не в пользу использования исключений:

без искльчений:
#include <cstdlib>
#include <cstdio>
#include <stdexcept>

#define length(arr) (sizeof(arr) / sizeof(arr[0]))

static unsigned int sum = 0;

static bool parse(int a)
{
    if (a < 0)
        return false;
    sum += a;

    return true;
}

int main()
{
    int a[100000];

    for (int i = 0; i< length(a); ++i)
        a[i] = i;

    a[length(a) / 2] = -1;
    a[(length(a) / 4) * 3] = -1;
    a[(length(a) / 6) * 5] = -1;
    a[(length(a) / 50) * 40] = -1;
    a[(length(a) / 1000) * 500] = -1;
    fprintf(stderr, "Inited\n");
    for (int i = 0; i< length(a); ++i) {
        if (!parse(a[i]))
            printf("Invalid value, i = %d\n", i);
    }
    printf("sum is: %u\n", sum);
    return EXIT_SUCCESS;
}



с исключениями:

#include <cstdlib>
#include <cstdio>
#include <stdexcept>

#define length(arr) (sizeof(arr) / sizeof(arr[0]))

static unsigned int sum = 0;

static void parse(int a)
{
    if (a < 0)
        throw std::runtime_error("Invalid value");
    sum += a;
}

int main()
{
    int a[100000];

    for (int i = 0; i< length(a); ++i)
        a[i] = i;

    a[length(a) / 2] = -1;
    a[(length(a) / 4) * 3] = -1;
    a[(length(a) / 6) * 5] = -1;
    a[(length(a) / 50) * 40] = -1;
    a[(length(a) / 1000) * 500] = -1;

    for (int i = 0; i< length(a); ++i) {
        try {
            parse(a[i]);
        } catch (const std::exception& e) {
            printf("Catch excepion, i = %d: %s\n",
                   i, e.what());
        }
    }
    printf("sum is: %u\n", sum);
    return EXIT_SUCCESS;
}


$ time ./exception
Catch excepion, i = 50000: Invalid value
Catch excepion, i = 75000: Invalid value
Catch excepion, i = 80000: Invalid value
Catch excepion, i = 83330: Invalid value
sum is: 704694374
real 0m 0.03s
user 0m 0.02s
sys 0m 0.02s

$./return_value
Inited
Invalid value, i = 50000
Invalid value, i = 75000
Invalid value, i = 80000
Invalid value, i = 83330
sum is: 704694374
real 0m 0.02s
user 0m 0.02s
sys 0m 0.01s


и
$ls -lh exception return_value
-rwxr-xr-x 1 root root 85.7k Jan 1 00:18 exception
-rwxr-xr-x 1 root root 63.8k Jan 1 00:18 return_value

как видите на довольно большое количество килобайт больше.

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

какие-нибудь предложение по изменению тестов?
Re[2]: ARM: C++ exceptions
От: Erop Россия  
Дата: 30.08.07 13:49
Оценка:
Здравствуйте, Аноним, Вы писали:

А>какие-нибудь предложение по изменению тестов?

1) Всё-таки надо измерять время работы кода в случае, когда исключений не происходит. Так как исключения -- это тки сбой. Нештатная ситуация.
2) Про размер тоже неплохо бы понять. Это RT на 20 кило подрос, или это код такой пухлый выходит (я думаю, что RT)

А вообще-то, ей-ей.
Если нужен такой сервис, то надёжнее в случае сбоя писать в лог и перезапускать сервис. Так на-а-а-амного надёжнее будет безотносительно к тому с исключениями там или без всё будет написано
Это ИМХО и если время позволяет, в смысле есть время перезапустить сервис. Правда можно иметь "сервис про запас" и перезапускать основной в как-нибудь в фоне.

Мало того, я бы ещё и по таймеру перезапускал тоже. Ну просто так, на всякий случай
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[9]: ARM: C++ exceptions
От: Шахтер Интернет  
Дата: 01.09.07 23:49
Оценка: -1
Здравствуйте, alexeiz, Вы писали:

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


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


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


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


E>>>>>>А зачем?

A>>>>>В смысле, зачем? Ты считаешь, что RAII — ненужная, бесполезная вещь? Объясни.
E>>>>Зачем лишаться RAII если не использовать исключения?

A>>>Захват ресурсов происходит в конструкторе (= resource aquisition is initialization). Без исключений ты не можешь проделать это в конструкторе по очевидным причинам.


Ш>>Бред.


A>Когда нечего сказать, начинаешь хамить?


Бред он и есть бред.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[2]: ARM: C++ exceptions
От: Шахтер Интернет  
Дата: 02.09.07 00:02
Оценка: :))
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


А>>Тема использовать или не использовать много раз обсуждалась,

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

А>>Есть ARM и 64 Мб, надо выбрать использовать или не использовать

А>>исключения, до написания основного кода,

А>>какие бы вы выбрали тесты для этого будь у вас железка и кроскомпилятор

А>>gcc 4.x для этого?

А>Провел первое тестирование, результаты не в пользу использования исключений:


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

А>с исключениями:


А>
А>#include <cstdlib>
А>#include <cstdio>
А>#include <stdexcept>

А>#define length(arr) (sizeof(arr) / sizeof(arr[0]))

А>static unsigned int sum = 0;

А>static void parse(int a)
А>{
А>    if (a < 0)
А>        throw std::runtime_error("Invalid value");
А>    sum += a;
А>}

А>int main()
А>{
А>    int a[100000];

А>    for (int i = 0; i< length(a); ++i)
А>        a[i] = i;

А>    a[length(a) / 2] = -1;
А>    a[(length(a) / 4) * 3] = -1;
А>    a[(length(a) / 6) * 5] = -1;
А>    a[(length(a) / 50) * 40] = -1;
А>    a[(length(a) / 1000) * 500] = -1;
А>
А>
А>  int i;
А>
А>try 
А>   {
А>    for (i = 0; i< length(a); ++i) 
А>       {
А>        parse(a[i]);
А>       } 
А>   } 
А>catch (const std::exception& e) 
А>  {
А>   printf("Catch excepion, i = %d: %s\n",
А>                   i, e.what());
А>   return EXIT_FAILURE; 
А>  }
А>
А>  printf("sum is: %u\n", sum);
А>  return EXIT_SUCCESS;
А>}

А>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[13]: ARM: C++ exceptions & RAII
От: Шахтер Интернет  
Дата: 02.09.07 00:09
Оценка: +1
Здравствуйте, alexeiz, Вы писали:

A>Освобождение в деструкторе — это не главная фишка RAII. Это вообще не фишка RAII. Этот принцип был в языке задолго до того, как появилась идея RAII. Главная фишка — захват в конструкторе и гарантия, что если это не получилось, то объект не создастся, и таким образом не будет невалидных объектов.


Незачет. Учи матчасть. Освобождение ресурсов в деструкторе -- это и есть RAII. Суть RAII очень проста -- конструктор используется длч захвата ресурса, деструктор для освобождения. Всё. Всё остально что ты написал -- твои домысли, не имеющие отношения к делу. Исключения ортогональны RAII. Они используются для обработки ошибочных ситуаций. Но ошибочные ситуации можно и без них обрабатывать. Применительно к RAII, если ресурс не удалось захватить, то объект конструируется в нулевом состоянии.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[13]: ARM: C++ exceptions & RAII
От: Шахтер Интернет  
Дата: 02.09.07 00:14
Оценка:
Здравствуйте, alexeiz, Вы писали:

Матчасть здесь
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[10]: ARM: C++ exceptions
От: alexeiz  
Дата: 02.09.07 21:56
Оценка:
Здравствуйте, Шахтер, Вы писали:

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


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


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


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


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


E>>>>>>>А зачем?

A>>>>>>В смысле, зачем? Ты считаешь, что RAII — ненужная, бесполезная вещь? Объясни.
E>>>>>Зачем лишаться RAII если не использовать исключения?

A>>>>Захват ресурсов происходит в конструкторе (= resource aquisition is initialization). Без исключений ты не можешь проделать это в конструкторе по очевидным причинам.


Ш>>>Бред.


A>>Когда нечего сказать, начинаешь хамить?


Ш>Бред он и есть бред.


А ты — хам. С хамами я не разговариваю.
Re: ARM: C++ exceptions
От: StevenIvanov США  
Дата: 03.09.07 09:09
Оценка:
Здравствуйте, Аноним, Вы писали:

А>...


А>какие бы вы выбрали тесты для этого будь у вас железка и кроскомпилятор

А>gcc 4.x для этого?

Если исключения используются в исключительных ситуацих, т.е. вероятность ошибки, которая отражается в коде исключительной ситуацией, мала, то из того, что известно мне (платформа arm-linux) могу сказать, что:
1) быстродействие не снижается.
2) размер кода несколько увеличивается (если я правильно мыслю это происходит в основном из-за созданий т.н. unwind таблиц, по которым происходит раскрутка стека).

Приходилось делать что-то вроде интерпретатора простенького скриптового языка с использованием boost (но без spirit — т.к. там есть багофичи не позволяющие компилировать без поддержки исключений). На все приложения были два блока try-catch. Снижения быстродействия не было замечено (сужу по работе с большим объемом данных).
Этот интерпретатор представлял единственный исполнимый модуль, который весил:
без поддержки исключений: 291 KB
с оной: 336 KB
Без поддержки RTTI скомпилировать не удалось из за ошибок в недрах boost::shared_ptr/function/что-то еще.
Re[2]: ARM: C++ exceptions
От: alexeiz  
Дата: 03.09.07 10:18
Оценка:
Здравствуйте, StevenIvanov, Вы писали:

SI>2) размер кода несколько увеличивается (если я правильно мыслю это происходит в основном из-за созданий т.н. unwind таблиц, по которым происходит раскрутка стека).


И еще из-из того, что код вызова деструкторов дублируется в конце функции. По крайней мере, так делает VC++ под ARM. Например для функции:
void foo()
{
    SomeObjWithDestructor o;
}

Генерируется код:
    push ebp    // object location on the stack
    call SomeObjWithDestructor::SomeObjWithDestructor()
    push ebp
    call SomeObjWithDestructor::~SomeObjWithDestructor()
    ret

    // unwinder
unwind:
    push ebp
    call SomeObjWithDestructor::~SomeObjWithDestructor()
    ret
Re[13]: ARM: C++ exceptions & RAII
От: COFF  
Дата: 03.09.07 13:42
Оценка: +1
Здравствуйте, alexeiz, Вы писали:

A>Освобождение в деструкторе — это не главная фишка RAII. Это вообще не фишка RAII. Этот принцип был в языке задолго до того, как появилась идея RAII. Главная фишка — захват в конструкторе и гарантия, что если это не получилось, то объект не создастся, и таким образом не будет невалидных объектов.


В реальном мире захват каких-то действительно интересных ресурсов на стадии инициализации ничего нам не гарантирует. Например, открытие файла на карточке — карточка может быть в любой момент вынута, на ней может кончиться место и т.д. То же самое с большинством других ресурсов. Поэтому валидность ресурса в том или ином виде надо проверять при каждой операции. В этом смысле, CFile file; file.Open(...) ничем не хуже, чем CFile file(...).
Re[14]: ARM: C++ exceptions & RAII
От: rusted Беларусь  
Дата: 04.09.07 09:18
Оценка: +1
Здравствуйте, COFF, Вы писали:

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


если карточка может быть вынута в любой момент, то проверка ресурса перед операцией не имеет особого смысла — нет гарантии, что "вынимание карточки" не произойдет между проверкой и операцией.
Re[15]: ARM: C++ exceptions & RAII
От: COFF  
Дата: 04.09.07 14:55
Оценка:
Здравствуйте, rusted, Вы писали:

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


R>если карточка может быть вынута в любой момент, то проверка ресурса перед операцией не имеет особого смысла — нет гарантии, что "вынимание карточки" не произойдет между проверкой и операцией.


В том или ином виде Т.е. в этом случае например ReadFile может вернуть ошибку. Я это к тому, что захват ресурса именно в конструкторе ничего не гарантирует и надо быть готовым к этому все-равно.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.