Tizen 2.0
От: enji  
Дата: 19.02.13 16:34
Оценка: :))) :))) :))
Стащил у eao197.

Будущее мобильной разработки, Tizen 2.0. По моему, шикарно... 6 new, 3 каста, 1 delete и даже E_SUCCESS
    void
    MyClass::HashMapSample(void)
    {
        HashMap map(SingleObjectDeleter);

        // Constructs a %HashMap instance with default capacity, load factor, hash code provider, and comparer
        map.Construct();

        map.Add(new String(L"Zero"), new Integer(0));       // map.GetCount() : 1, map : (Zero -> 0)
        map.Add(new String(L"One"), new Integer(1));        // map.GetCount() : 2, map : (Zero -> 0), (one -> 1)
        map.Add(new String(L"Two"), new Integer(2));        // map.GetCount() : 3, map : (Zero -> 0), (one -> 1), (Two -> 2)

        // Gets a value with the specified key
        Integer*    pValue = static_cast< Integer* > (map.GetValue(String(L"Zero")));       // pValue : 0

        // Removes the value with the specified key
        map.Remove(String(L"Zero"));                                            // map.GetCount() : 2, map : (one -> 1), (Two -> 2)

        // Uses an enumerator to access elements in the list
        IMapEnumerator* pMapEnum = map.GetMapEnumeratorN();
        String* pKey = null;
        while (pMapEnum->MoveNext() == E_SUCCESS)
        {
            pKey = static_cast< String* > (pMapEnum->GetKey());
            pValue = static_cast< Integer* > (pMapEnum->GetValue());
        }

        delete pMapEnum;

        // Deallocates all objects
        // Because the destructor calls RemoveAll() internally, you don't need to call RemoveAll() to destroy all elements at the end.
        map.RemoveAll();

    }


01.03.13 13:58: Перенесено модератором из 'C/C++'. Извините, но размер дискуссии говорит за себя. — Кодт
Re: Tizen 2.0
От: niXman Ниоткуда https://github.com/niXman
Дата: 19.02.13 16:46
Оценка:
Здравствуйте, enji, Вы писали:

E>Стащил у eao197.

это кто/что ?

E>Будущее мобильной разработки, Tizen 2.0. По моему, шикарно... 6 new, 3 каста, 1 delete и даже E_SUCCESS

вот не уверен, это сарказм, или как?
new и delete, действительно провоцируют вопросы...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: Tizen 2.0
От: pzhy  
Дата: 19.02.13 17:27
Оценка:
Здравствуйте, enji, Вы писали:

E>Стащил у eao197.


E>Будущее мобильной разработки, Tizen 2.0. По моему, шикарно... 6 new, 3 каста, 1 delete и даже E_SUCCESS

E>
E>    void
E>    MyClass::HashMapSample(void)
E>    {
E>        HashMap map(SingleObjectDeleter);

E>        // Constructs a %HashMap instance with default capacity, load factor, hash code provider, and comparer
E>        map.Construct();

E>        map.Add(new String(L"Zero"), new Integer(0));       // map.GetCount() : 1, map : (Zero -> 0)
E>        map.Add(new String(L"One"), new Integer(1));        // map.GetCount() : 2, map : (Zero -> 0), (one -> 1)
E>        map.Add(new String(L"Two"), new Integer(2));        // map.GetCount() : 3, map : (Zero -> 0), (one -> 1), (Two -> 2)

E>        // Gets a value with the specified key
E>        Integer*    pValue = static_cast< Integer* > (map.GetValue(String(L"Zero")));       // pValue : 0

E>        // Removes the value with the specified key
E>        map.Remove(String(L"Zero"));                                            // map.GetCount() : 2, map : (one -> 1), (Two -> 2)

E>        // Uses an enumerator to access elements in the list
E>        IMapEnumerator* pMapEnum = map.GetMapEnumeratorN();
E>        String* pKey = null;
E>        while (pMapEnum->MoveNext() == E_SUCCESS)
E>        {
E>            pKey = static_cast< String* > (pMapEnum->GetKey());
E>            pValue = static_cast< Integer* > (pMapEnum->GetValue());
E>        }

E>        delete pMapEnum;

E>        // Deallocates all objects
E>        // Because the destructor calls RemoveAll() internally, you don't need to call RemoveAll() to destroy all elements at the end.
E>        map.RemoveAll();

E>    }
E>


так ведь Sample.
Re[2]: Tizen 2.0
От: MTD https://github.com/mtrempoltsev
Дата: 19.02.13 17:31
Оценка:
Здравствуйте, niXman, Вы писали:

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


E>>Стащил у eao197.

X>это кто/что ?

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

X>вот не уверен, это сарказм, или как?


Сарказм-сарказм
Re[2]: Tizen 2.0
От: MTD https://github.com/mtrempoltsev
Дата: 19.02.13 17:31
Оценка:
Здравствуйте, pzhy, Вы писали:

P>так ведь Sample.


Спасибо, больше не надо.
Re: Tizen 2.0
От: MTD https://github.com/mtrempoltsev
Дата: 19.02.13 17:36
Оценка: 1 (1) :))
Здравствуйте, enji, Вы писали:

Мысли разработчика.

E> void

E> MyClass::HashMapSample(void)

Как я скучаю по старому доброму С и пятидюймовым дискетам.

E> HashMap map(SingleObjectDeleter);

E> map.Add(new String(L"Zero"), new Integer(0)); // map.GetCount() : 1, map : (Zero -> 0)
E> map.Add(new String(L"One"), new Integer(1)); // map.GetCount() : 2, map : (Zero -> 0), (one -> 1)
E> map.Add(new String(L"Two"), new Integer(2)); // map.GetCount() : 3, map : (Zero -> 0), (one -> 1),

Черт! Кто мне подложил книжку по яве?

E> // Gets a value with the specified key

E> Integer* pValue = static_cast< Integer* > (map.GetValue(String(L"Zero"))); // pValue : 0

Избегайте кастов в стиле С! И пусть не говорят, что я не знаю плюсов.
Re: Tizen 2.0
От: Ops Россия  
Дата: 19.02.13 18:38
Оценка:
Здравствуйте, enji, Вы писали:

E>Будущее мобильной разработки, Tizen 2.0. По моему, шикарно... 6 new, 3 каста, 1 delete и даже E_SUCCESS


А Tizen тут причем? Код как код, на govnokod.ru намного круче можно найти, а такого везде полно.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[2]: Tizen 2.0
От: enji  
Дата: 19.02.13 19:06
Оценка:
Здравствуйте, Ops, Вы писали:

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


E>>Будущее мобильной разработки, Tizen 2.0. По моему, шикарно... 6 new, 3 каста, 1 delete и даже E_SUCCESS


Ops>А Tizen тут причем?


это код из его хелпа. И интерфейс контейнера намекает нам, что такого кода будет много...

Ops>Код как код, на govnokod.ru намного круче можно найти, а такого везде полно.


Ну это не говнокод.ру, а инновационный продукт интела и самсунга, как я понимаю...
Re: Tizen 2.0
От: minorlogic Украина  
Дата: 19.02.13 19:19
Оценка: 1 (1) +6
Только не говорите что это C++
... << RSDN@Home 1.2.0 alpha 5 rev. 1539>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[3]: Tizen 2.0
От: Ops Россия  
Дата: 19.02.13 21:18
Оценка:
Здравствуйте, enji, Вы писали:

Ops>>А Tizen тут причем?

E>это код из его хелпа. И интерфейс контейнера намекает нам, что такого кода будет много...
Ops>>Код как код, на govnokod.ru намного круче можно найти, а такого везде полно.
E>Ну это не говнокод.ру, а инновационный продукт интела и самсунга, как я понимаю...

Как вариант, хелп спихнули на студентов?
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re: Tizen 2.0
От: UA Украина  
Дата: 19.02.13 22:30
Оценка: :)
Здравствуйте, enji, Вы писали:

Пропустили вызов
map.Destruct();

Re: Tizen 2.0
От: landerhigh Пират  
Дата: 20.02.13 00:53
Оценка: +6 :)))
Здравствуйте, enji, Вы писали:

E>Стащил у eao197.


Шутки в сторону, но это же ахтунг и аллес капут в одном флаконе

The object is not fully constructed after this constructor is called. For full construction,
the Construct() method must be called right after calling this constructor.


тынц

Ой, а тут еще вкусное

Error handling in Tizen works differently compared to standard C++. Tizen uses error results instead of C++ exceptions, due to historical reasons.


Как говорят на детском форуме, закапывайте.
www.blinnov.com
Re: Вот еще, или я, кажется, читать разучился
От: landerhigh Пират  
Дата: 20.02.13 03:46
Оценка:
Здравствуйте, enji, Вы писали:


Q: Why does Tizen use two-phase construction?

A: Tizen does not use the C++ exception mechanism. This reduces its footprint and runtime overhead. As a result, any exception occurring in C++ object construction cannot be reported to the application.

Furthermore, when a failure occurs in allocating resources during an object's construction, the object is partially constructed and its destructor is not called, possibly causing a resource leak. To resolve these problems, Tizen uses the two-phase construction idiom for many classes where exceptions must be reported to Tizen native applications. For more information, see Two-phase Construction.
Q: What happens if I do not call a Construct() method?

A: Some methods throw an exception, and some return a probably meaningless value. In any case, Tizen does not guarantee the reliability or consistency of user applications. You must make sure that the Construct()method is invoked properly before an instance of a two-phase construction class is used.



ЭТО как?
www.blinnov.com
Re[2]: Вот еще, или я, кажется, читать разучился
От: jazzer Россия Skype: enerjazzer
Дата: 20.02.13 04:08
Оценка: +2
Здравствуйте, landerhigh, Вы писали:

Я так понял, у них под исключениями понимаются не исключения С++, а коды возврата E_*.
Либо у них могут вылетать исключения в случае попытки использования объекта до вызова Construct().
В общем, они пошли по пути Симбиана, в котором не было исключений, типа слишком тяжелый механизм для мобильных устройств (при этом они собираются запускать Java, где исключения летают только в путь ).
Т.е. получается что-то между Си и С++.
Имхо, правильнее относиться как к Си с небольшим сиплюсовидным сахаром.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: Вот еще, или я, кажется, читать разучился
От: landerhigh Пират  
Дата: 20.02.13 05:27
Оценка:
Здравствуйте, jazzer, Вы писали:

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


J>Я так понял, у них под исключениями понимаются не исключения С++, а коды возврата E_*.


Я вот документацию привык понимать буквально.

J>Либо у них могут вылетать исключения в случае попытки использования объекта до вызова Construct().


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

J>В общем, они пошли по пути Симбиана, в котором не было исключений, типа слишком тяжелый механизм для мобильных устройств (при этом они собираются запускать Java, где исключения летают только в путь ).


Вроде бы, собственно механизм исключений в Java достаточно легковесный. Однако сама идея экономить на спичках (икключениях), чтобы потом запускать Java попахивает каким-то идиотизмом.
www.blinnov.com
Re[4]: Вот еще, или я, кажется, читать разучился
От: jazzer Россия Skype: enerjazzer
Дата: 20.02.13 06:22
Оценка:
Здравствуйте, landerhigh, Вы писали:

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


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


J>>Я так понял, у них под исключениями понимаются не исключения С++, а коды возврата E_*.


L>Я вот документацию привык понимать буквально.


Я вот эту страничку имел в виду: https://developer.tizen.org/help/topic/org.tizen.native.appprogramming/html/basics_tizen_programming/exception_check.htm

Out-of-memory Exception

Almost all APIs, except simple getter methods, can potentially throw an E_OUT_OF_MEMORY exception, although the APIs do not specify the out-of-memory (OOM) exception.
...

if (GetLastResult() == E_OUT_OF_MEMORY)


J>>Либо у них могут вылетать исключения в случае попытки использования объекта до вызова Construct().


L>Да двухфазная инициализация — это жесть. Получается, что тебе дали объект, но сказать, можно ли его использовать, забыли. Особенно забавно на этом фоне выглядят конструкторы копирования

Ну, может, у них есть какой-нть is_initialized()

J>>В общем, они пошли по пути Симбиана, в котором не было исключений, типа слишком тяжелый механизм для мобильных устройств (при этом они собираются запускать Java, где исключения летают только в путь ).

L>Вроде бы, собственно механизм исключений в Java достаточно легковесный. Однако сама идея экономить на спичках (икключениях), чтобы потом запускать Java попахивает каким-то идиотизмом.
+1
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: Tizen 2.0
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 20.02.13 09:00
Оценка:
Здравствуйте, Ops, Вы писали:

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


Ops>>>А Tizen тут причем?

E>>это код из его хелпа. И интерфейс контейнера намекает нам, что такого кода будет много...
Ops>>>Код как код, на govnokod.ru намного круче можно найти, а такого везде полно.
E>>Ну это не говнокод.ру, а инновационный продукт интела и самсунга, как я понимаю...

Ops>Как вариант, хелп спихнули на студентов?

Хелп спихнули на нативов — корейцев. Как, впрочем, и многое другое.
Sic luceat lux!
Re[4]: Tizen 2.0
От: MTD https://github.com/mtrempoltsev
Дата: 20.02.13 09:04
Оценка:
Здравствуйте, Ops, Вы писали:

Ops>Как вариант, хелп спихнули на студентов?


Судя по коду не только хелп. Пример:

IMapEnumerator* pMapEnum = map.GetMapEnumeratorN();
delete pMapEnum;


Это же прекрасно, когда метод мапы возвращает объект который надо не забыть удалить!
Re: Tizen 2.0
От: niXman Ниоткуда https://github.com/niXman
Дата: 20.02.13 09:10
Оценка:
Здравствуйте, enji, Вы писали:

E> HashMap map(SingleObjectDeleter);


E> // Constructs a %HashMap instance with default capacity, load factor, hash code provider, and comparer

E> map.Construct();

E> map.Add(new String(L"Zero"), new Integer(0)); // map.GetCount() : 1, map : (Zero -> 0)

E> map.Add(new String(L"One"), new Integer(1)); // map.GetCount() : 2, map : (Zero -> 0), (one -> 1)
E> map.Add(new String(L"Two"), new Integer(2)); // map.GetCount() : 3, map : (Zero -> 0), (one -> 1), (Two -> 2)
так это что же получается, у них и шаблонов нет и смарт указателей тожа? оО
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: Вот еще, или я, кажется, читать разучился
От: Mr.Delphist  
Дата: 20.02.13 09:22
Оценка:
Здравствуйте, jazzer, Вы писали:

J>В общем, они пошли по пути Симбиана, в котором не было исключений, типа слишком тяжелый механизм для мобильных устройств

Выходит, не мне одному это показалось знакомым
Re[2]: Tizen 2.0
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 20.02.13 09:34
Оценка: :)
Здравствуйте, niXman, Вы писали:

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


E>> HashMap map(SingleObjectDeleter);


E>> // Constructs a %HashMap instance with default capacity, load factor, hash code provider, and comparer

E>> map.Construct();

E>> map.Add(new String(L"Zero"), new Integer(0)); // map.GetCount() : 1, map : (Zero -> 0)

E>> map.Add(new String(L"One"), new Integer(1)); // map.GetCount() : 2, map : (Zero -> 0), (one -> 1)
E>> map.Add(new String(L"Two"), new Integer(2)); // map.GetCount() : 3, map : (Zero -> 0), (one -> 1), (Two -> 2)
X>так это что же получается, у них и шаблонов нет и смарт указателей тожа? оО
X>
Есть там всё.
Sic luceat lux!
Re[3]: Tizen 2.0
От: niXman Ниоткуда https://github.com/niXman
Дата: 20.02.13 09:37
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Есть там всё.

т.е. это писатели экзампла об этом незнают?

зы
вообще страшно от того, что эти же писатели экзампла, могли кодить не только экзамплы %)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: Tizen 2.0
От: enji  
Дата: 20.02.13 09:43
Оценка:
Здравствуйте, niXman, Вы писали:

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


E>> HashMap map(SingleObjectDeleter);


E>> // Constructs a %HashMap instance with default capacity, load factor, hash code provider, and comparer

E>> map.Construct();

E>> map.Add(new String(L"Zero"), new Integer(0)); // map.GetCount() : 1, map : (Zero -> 0)

E>> map.Add(new String(L"One"), new Integer(1)); // map.GetCount() : 2, map : (Zero -> 0), (one -> 1)
E>> map.Add(new String(L"Two"), new Integer(2)); // map.GetCount() : 3, map : (Zero -> 0), (one -> 1), (Two -> 2)
X>так это что же получается, у них и шаблонов нет и смарт указателей тожа? оО
X>

Там у контейнеров идеология явовская, как я понимаю. Есть интерфейсы, от них наследуются конкретные контейнеры. В результате можно без шаблонов использовать контейнеры неизвестного типа, но зато они становятся неоднородными (или как это правильно называется) — можно запихать int, попытаться прочитать строку и после static_cast словить массу интересного
Re[4]: Tizen 2.0
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 20.02.13 09:44
Оценка:
Здравствуйте, niXman, Вы писали:

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


K>>Есть там всё.

X>т.е. это писатели экзампла об этом незнают?
Как видишь.
X>зы
X>вообще страшно от того, что эти же писатели экзампла, могли кодить не только экзамплы %)
Ядро, ЕМНИП, там вполне неплохо сделано.
Sic luceat lux!
Re[3]: Tizen 2.0
От: niXman Ниоткуда https://github.com/niXman
Дата: 20.02.13 09:47
Оценка:
Здравствуйте, enji, Вы писали:

E>(или как это правильно называется)

гетерогенные?

на яве я не писатель, но от описанной тобою идеалогии становится непонятно, почему на фоне ява, с++ считается "опасным" ЯП %)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: Tizen 2.0
От: Jack128  
Дата: 20.02.13 09:50
Оценка:
Здравствуйте, enji, Вы писали:

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


как ты туда запихнешь int, если контейнер без шаблонов параметром Object* принимает??
Re[4]: Tizen 2.0
От: Jack128  
Дата: 20.02.13 10:11
Оценка:
Здравствуйте, niXman, Вы писали:

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


E>>(или как это правильно называется)

X>гетерогенные?

X>на яве я не писатель, но от описанной тобою идеалогии становится непонятно, почему на фоне ява, с++ считается "опасным" ЯП %)


в джаве невозвожно сделать так


struct Object
{
    virtual ~Object() {}
};
struct Integer: Object
{
    int value;
    Integer(int val) : value(val){}    
};
int main()
{
    Object * o = new Integer(10);
    Integer * i = static_cast<Integer *>(o);
}



закастить предка к потомку можно только с проверкой во время выполнения(через dynamic_cast). то что в плюсах выделенная строчка компилируется — это именно плюсовый касяк. но мне либо dynamic_cast либо reinterpret_cast.
Re[5]: Tizen 2.0
От: Evgeny.Panasyuk Россия  
Дата: 20.02.13 10:41
Оценка:
Здравствуйте, Jack128, Вы писали:

J>
J>int main()
J>{
J>    Object * o = new Integer(10);
J>    Integer * i = static_cast<Integer *>(o);
J>}
J>

J>закастить предка к потомку можно только с проверкой во время выполнения(через dynamic_cast). то что в плюсах выделенная строчка компилируется — это именно плюсовый касяк.

Это не косяк, а фича — don't pay for what you don't use.
Если ты знаешь тип объекта например по встроенному TypeID, or by any other means (например как в твоём примере выше) — ты можешь не платить за dynamic_cast.
Более того, RTTI не всегда доступен.

J>но мне либо dynamic_cast либо reinterpret_cast


reinterpret_cast это очень low-level механизм, стандартом предоставляются мизерные гарантии по поводу него.
Тебе скорей всего просто не хватает polymorphic_downcast.

The C++ built-in static_cast can be used for efficiently downcasting pointers to polymorphic objects, but provides no error detection for the case where the pointer being cast actually points to the wrong derived class. The polymorphic_downcast template retains the efficiency of static_cast for non-debug compilations, but for debug compilations adds safety via an assert() that a dynamic_cast succeeds.


P.S. Там где есть templates/generics — необходимость в кастах возникает намного реже.
Re[6]: Tizen 2.0
От: Jack128  
Дата: 20.02.13 11:52
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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


J>>
J>>int main()
J>>{
J>>    Object * o = new Integer(10);
J>>    Integer * i = static_cast<Integer *>(o);
J>>}
J>>

J>>закастить предка к потомку можно только с проверкой во время выполнения(через dynamic_cast). то что в плюсах выделенная строчка компилируется — это именно плюсовый касяк.

EP>Это не косяк, а фича — don't pay for what you don't use.

EP>Если ты знаешь тип объекта например по встроенному TypeID, or by any other means (например как в твоём примере выше) — ты можешь не платить за dynamic_cast.
EP>Более того, RTTI не всегда доступен.

J>>но мне либо dynamic_cast либо reinterpret_cast


EP>reinterpret_cast это очень low-level механизм, стандартом предоставляются мизерные гарантии по поводу него.

А, понял в чем мой прокол. Если у нас используется множественное наследование, то как я понимаю reinterpret_cast может не дать корректный результат, даже если по факту аргумент является указателем на Integer. А динамик — дает пенальти в ран тайм. статик_каст — сидит посередине.
Сенкс.
Re[5]: Tizen 2.0
От: rusted Беларусь  
Дата: 20.02.13 11:58
Оценка:
Здравствуйте, MTD, Вы писали:

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


Ops>>Как вариант, хелп спихнули на студентов?


MTD>Судя по коду не только хелп. Пример:


MTD>
MTD>IMapEnumerator* pMapEnum = map.GetMapEnumeratorN();
MTD>delete pMapEnum;
MTD>


MTD>Это же прекрасно, когда метод мапы возвращает объект который надо не забыть удалить!


Самое восхитительое, что про необходимость удаления в документации GetMapEnumeratorN не сказано (или вот эта буква N в конце имени метода говорит об этом?)

Законы Мерфи были сформулированы уже столько поколений назад, а люди и сейчас продолжают строгать API, с которыми накосячить проще, чем сделать всё правильно. Ладно у них нет исключений, но почему из таких методов нельзя возвращать какой-нибудь вариант unique_ptr?
Re: это не Tizen 2.0!!!!
От: cencio Украина http://ua-coder.blogspot.com
Дата: 20.02.13 12:34
Оценка:
Здравствуйте, enji, Вы писали:

E>Стащил у eao197.


E>Будущее мобильной разработки, Tizen 2.0. По моему, шикарно... 6 new, 3 каста, 1 delete и даже E_SUCCESS


А при чем здесь Tizen? Ваш eao197 просто не в теме. Самсунг как и обещал еще в прошлом году, добавил поддержку апи Бады.
Сравните:
здесь tizen
и
здесь бада
tizen bada
Re[2]: это не Tizen 2.0!!!!
От: niXman Ниоткуда https://github.com/niXman
Дата: 20.02.13 12:46
Оценка: +1
Здравствуйте, cencio, Вы писали:

C>А при чем здесь Tizen? Ваш eao197 просто не в теме. Самсунг как и обещал еще в прошлом году, добавил поддержку апи Бады.

C>Сравните:
C>здесь tizen
C>и
C>здесь бада
я не уверен, что из этого хуже %)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[5]: Tizen 2.0
От: Ops Россия  
Дата: 20.02.13 13:11
Оценка:
Здравствуйте, MTD, Вы писали:

MTD>Судя по коду не только хелп. Пример:

MTD>
MTD>IMapEnumerator* pMapEnum = map.GetMapEnumeratorN();
MTD>delete pMapEnum;
MTD>

MTD>Это же прекрасно, когда метод мапы возвращает объект который надо не забыть удалить!

Не разбирался, что там к чему, HashMap — тип из какой-нибудь основной библиотеки? Она обязательна для использования (часть фич только через нее, и т.п.)?
Или, может, это костыль для совместимости с чем-то еще, а систему можно дергать совсем по-другому?
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[3]: Вот еще, или я, кажется, читать разучился
От: Nikе Россия  
Дата: 20.02.13 13:47
Оценка: +1
Здравствуйте, jazzer, Вы писали:

J>В общем, они пошли по пути Симбиана, в котором не было исключений, типа слишком тяжелый механизм для мобильных устройств

Они там были где-то с 2003 года, но интерфейс собственно операционки не переписывали по историческим причинам. ИМХО — это было важной доской гроба.
Нужно разобрать угил.
Re[5]: Вот еще, или я, кажется, читать разучился
От: landerhigh Пират  
Дата: 20.02.13 13:50
Оценка:
Здравствуйте, jazzer, Вы писали:

L>>Да двухфазная инициализация — это жесть. Получается, что тебе дали объект, но сказать, можно ли его использовать, забыли. Особенно забавно на этом фоне выглядят конструкторы копирования

J>Ну, может, у них есть какой-нть is_initialized()

Ну, тут можно сказать лишь одно — даешь оплату за строчки кода!

Интересно, кто-то наверняка ведь должен был оценить медианный размер кода, в котором макаро оверхед от анализа кодов возврата на каждый чих начинает сводить на нет выгоду от отказа от исключений, которые имеют "footprint and runtime overhead"?
www.blinnov.com
Re: Tizen 2.0
От: Шахтер Интернет  
Дата: 20.02.13 14:05
Оценка: +1
Здравствуйте, enji, Вы писали:

E>Будущее мобильной разработки, Tizen 2.0.


Это не будующее, а позапрошлое.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[6]: Вот еще, или я, кажется, читать разучился
От: Evgeny.Panasyuk Россия  
Дата: 20.02.13 14:39
Оценка: +1
Здравствуйте, landerhigh, Вы писали:

L>Интересно, кто-то наверняка ведь должен был оценить медианный размер кода, в котором макаро оверхед от анализа кодов возврата на каждый чих начинает сводить на нет выгоду от отказа от исключений, которые имеют "footprint and runtime overhead"?


Я слышал, что при happy-path (когда исключения не кидаются) x64 код получается даже быстрее чем аналогичный с "if(err1) goto ERR1;".
Сам тестов не делал — надо что-нибудь запилить назло тем кто ноет про медленные исключения.

Насколько я себе представляю — "вредный" overhead от исключений есть только тогда, когда компилятор предполагает что функция которую он не видит, может кинуть (которая на самом деле ничего не кидает). Но в C++11 уже есть noexcept.

P.S.

My typical reply is also somewhere along the same lines: if you don't like to use exceptions, then just don't use them. Leave that job to the professionals

(c) не моё
Re[7]: Вот еще, или я, кажется, читать разучился
От: niXman Ниоткуда https://github.com/niXman
Дата: 20.02.13 14:51
Оценка: 15 (4) +1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Я слышал, что при happy-path (когда исключения не кидаются) x64 код получается даже быстрее чем аналогичный с "if(err1) goto ERR1;".

EP>Сам тестов не делал — надо что-нибудь запилить назло тем кто ноет про медленные исключения.

я тестировал оверхед создаваемый SJLJ реализацией исключений в венде(мингв), когда сами исключения не бросаются. т.е. интересен был побочный эффект.
оказалось, 1.4-4.1 процента.

как известно, SJLJ это дорогие исключения. но, как показывает мой тест, я готов платить 5% за то чтоб обрабатывать коды ошибок через каждые пять строк =)
DWARF как и SEH — не создают побочный оверхед. так что, я совершенно не понимаю стоимости аргументации не использовать исключения.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[8]: Вот еще, или я, кажется, читать разучился
От: niXman Ниоткуда https://github.com/niXman
Дата: 20.02.13 14:55
Оценка:
Здравствуйте, niXman, Вы писали:

тьфу %)

X>я готов платить 5% за то чтоб обрабатывать коды ошибок через каждые пять строк =)

я готов платить 5% за то чтоб не обрабатывать коды ошибок через каждые пять строк =)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: Вот еще, или я, кажется, читать разучился
От: minorlogic Украина  
Дата: 20.02.13 15:21
Оценка:
Ужас , ужас, ужас.
... << RSDN@Home 1.2.0 alpha 5 rev. 1539>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[9]: Вот еще, или я, кажется, читать разучился
От: Evgeny.Panasyuk Россия  
Дата: 20.02.13 17:08
Оценка:
Здравствуйте, niXman, Вы писали:

X>я готов платить 5% за то чтоб не обрабатывать коды ошибок через каждые пять строк =)


На 5% больше по сравнению с чем?
С кодом вообще без обработки ошибок?
Или с полным эквивалентом в виде "if(errorN) goto ErrorN;" ?
Re[10]: Вот еще, или я, кажется, читать разучился
От: niXman Ниоткуда https://github.com/niXman
Дата: 20.02.13 19:15
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>На 5% больше по сравнению с чем?

EP>С кодом вообще без обработки ошибок?
да.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: Вот еще, или я, кажется, читать разучился
От: artem.komisarenko Украина  
Дата: 20.02.13 20:50
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>A: Tizen does not use the C++ exception mechanism. This reduces its footprint and runtime overhead. As a result, any exception occurring in C++ object construction cannot be reported to the application.


Знаю я одни таких дебилов из одной Г конторы, которые редусили использование памяти на мобилках и не включили в стандартную поставку libstdc++ и поддержку исключений. В результате каждое второе нативное приложение стало таскать с собой собственную версию libstdc++.
Экономисты б***
Re[11]: Вот еще, или я, кажется, читать разучился
От: Evgeny.Panasyuk Россия  
Дата: 20.02.13 21:02
Оценка: 9 (3)
Здравствуйте, niXman, Вы писали:

EP>>На 5% больше по сравнению с чем?

EP>>С кодом вообще без обработки ошибок?
X>да.

Набросал тест exceptions vs if-error-goto:
В случае exceptions, код следующего вида:
static void call()
{
    Holder h0;
    exceptions<iter-1>::call(); // may throw

    Holder h1;
    exceptions<iter-1>::call(); // may throw
    // ...
}

В случае if-error-goto:
static bool call()
{
    bool result = true;
    void *d0;
    void *d1;
    // ...

    d0 = mallocator();
    if(! (result=ifgoto<iter-1>::call()) ) // may fail
        goto ERROR0;

    d1 = mallocator();
    if(! (result=ifgoto<iter-1>::call()) ) // may fail
        goto ERROR1;
    // ...

    // ...
    ERROR1: free(d1);
    ERROR0: free(d0);

    return result;
}

  реализация
#include <boost/range/algorithm/nth_element.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/noncopyable.hpp>
#include <boost/timer/timer.hpp>
//#include <boost/timer.hpp>

#include <iostream>
#include <ostream>
#include <cstdlib>
#include <vector>
#include <ctime>

using namespace std;
using namespace boost;

// ______________________________ //

const int series = 33;
const int deepness = 5;
#define REPEATS 32

// ______________________________ //

bool error_check()
{
    //return time(0) < 1;
    static volatile bool t = false;
    return t;
}
void *mallocator()
{
    return malloc(4);
}

// ______________________________ //

class Holder : private noncopyable
{
    void *data;
public:
    Holder()
        : data(mallocator())
    {}
    ~Holder()
    {
        free(data);
    }
};
template<int iter> struct exceptions
{
    static void call()
    {
        #define EXP_REP(z, i, _) Holder h##i; exceptions<iter-1>::call();
            BOOST_PP_REPEAT(REPEATS,EXP_REP,t)
    }
};
template<> struct exceptions<0>
{
    static void call()
    {
        if(error_check()) throw false;
    }
};

// ______________________________ //

template<int iter> struct ifgoto
{
    static bool call()
    {
        bool result = true;

        #define IFG_REP0(z, i, _) void *d##i;
            BOOST_PP_REPEAT(REPEATS,IFG_REP0,t)

        #define IFG_REP1(z, i, _) d##i = mallocator(); if(! (result=ifgoto<iter-1>::call()) ) goto ERROR##i;
            BOOST_PP_REPEAT(REPEATS,IFG_REP1,t)

        #define IFG_REP_AUX(i) BOOST_PP_CAT(ERROR,i): free(BOOST_PP_CAT(d,i));
        #define IFG_REP2(z, i, _) IFG_REP_AUX( BOOST_PP_SUB(BOOST_PP_SUB(REPEATS,1),i) )
            BOOST_PP_REPEAT(REPEATS,IFG_REP2,t)

        return result;
    }
};
template<> struct ifgoto<0>
{
    static bool call()
    {
        return error_check() == false;
    }
};

// ______________________________ //

template<template<int> class test_case>
void test(const char *name)
{
    cout << name;
    vector<double> times;
    for(int i=0;i!=series;++i)
    {
        //timer t;
        timer::cpu_timer t;
        test_case<deepness>::call();
        times.push_back(double(t.elapsed().user));
    }
    vector<double>::iterator median = times.begin() + times.size()/2;
    nth_element(times,median);
    cout << "\tmedian is " << (*median)*1e-6 << "ms" << endl;
}

int main()
{
    try
    {
        for(int i=0;i!=2;++i)
        {
            test<exceptions>("exceptions");
            test<ifgoto>("if-error-goto");
        }
    }
    catch(...){}
}

В обоих случаях сравниваются happy-path.
Результаты MSVC2010SP1Rel x64, Release:
С включёнными исключениями(default, /EHsc):
exceptions      median is 1731.61ms
if-error-goto   median is 1762.81ms
exceptions      median is 1731.61ms
if-error-goto   median is 1747.21ms

С выключенными исключениями (чтобы исключить их возможное влияние на if-error-goto):
exceptions      median is 1326.01ms
if-error-goto   median is 1716.01ms
exceptions      median is 1326.01ms
if-error-goto   median is 1716.01ms

1731.61 / 1716.01 ~= 1.0091
Re[12]: Вот еще, или я, кажется, читать разучился
От: MTD https://github.com/mtrempoltsev
Дата: 20.02.13 21:19
Оценка: 23 (3)
Мои пять копеек:


mt@mint14 ~/Desktop $ g++ exceptions.cpp -O3
mt@mint14 ~/Desktop $ time ./a.out

real 0m53.612s
user 0m49.559s
sys 0m0.028s
mt@mint14 ~/Desktop $ gcc error_code.c -O3 -std=c99
mt@mint14 ~/Desktop $ time ./a.out

real 0m53.730s
user 0m49.647s
sys 0m0.024s




Код:

const int MAX_COUNT = 100000000;

char buf;
int count = 0;

void open()
{
    if (++count == MAX_COUNT)
    {
        count = 0;
        throw 1;
    }
}

void read(char* c)
{
    *c = buf;
    if (++count == MAX_COUNT)
    {
        count = 0;
        throw 1;
    }
}

void send(char* c)
{
    buf = *c;
    if (++count == MAX_COUNT)
    {
        count = 0;
        throw 1;
    }
}

int main()
{
    for (int i = 0; i != 1000; ++i)
    {
        try
        {
            open();
            char c;
            for (int j = 0; j != MAX_COUNT + 1; ++j)
            {
                read(&c);
                send(&c);
            }
        }
        catch (const int&)
        {
        }
    }
}



#define MAX_COUNT 100000000

char buf;
int count = 0;

int open()
{
    if (++count == MAX_COUNT)
    {
        count = 0;
        return -1;
    }
    return 0;
}

int read(char* c)
{
    *c = buf;
    if (++count == MAX_COUNT)
    {
        count = 0;
        return -1;
    }
    return 0;
}

int send(char* c)
{
    buf = *c;
    if (++count == MAX_COUNT)
    {
        count = 0;
        return -1;
    }
    return 0;
}

int main()
{
    for (int i = 0; i != 1000; ++i)
    {
        if (open() == -1)
            continue;
        char c;
        for (int j = 0; j != MAX_COUNT + 1; ++j)
        {
            if (read(&c) == -1)
                break;
            if (send(&c) == -1)
                break;
        }
    }
}
Re[3]: Вот еще, или я, кажется, читать разучился
От: landerhigh Пират  
Дата: 21.02.13 00:01
Оценка:
Здравствуйте, artem.komisarenko, Вы писали:

L>>A: Tizen does not use the C++ exception mechanism. This reduces its footprint and runtime overhead. As a result, any exception occurring in C++ object construction cannot be reported to the application.


AK>Знаю я одни таких дебилов из одной Г конторы,


Я, кажется, знаю эту контору

AK>которые редусили использование памяти на мобилках и не включили в стандартную поставку libstdc++ и поддержку исключений.


Ага, а для еще большей экономии поставили Java-машину на мобилки. Впрочем, с NDKr5 исключения стали доступны.

AK>В результате каждое второе нативное приложение стало таскать с собой собственную версию libstdc++.


А вот это да

AK>Экономисты б***


Профессиональные взвешиватели боингов, чо.
www.blinnov.com
Re[13]: Вот еще, или я, кажется, читать разучился
От: landerhigh Пират  
Дата: 21.02.13 00:22
Оценка:
Здравствуйте, MTD, Вы писали:

Подытожим — runtime оверхед незначительный, если вообще есть.
Осталось оценить увеличение размера кода (таблицы обработчиков и все такое).
www.blinnov.com
Re[6]: Вот еще, или я, кажется, читать разучился
От: jazzer Россия Skype: enerjazzer
Дата: 21.02.13 01:29
Оценка: 1 (1) +3
Здравствуйте, landerhigh, Вы писали:

L>Интересно, кто-то наверняка ведь должен был оценить медианный размер кода, в котором макаро оверхед от анализа кодов возврата на каждый чих начинает сводить на нет выгоду от отказа от исключений, которые имеют "footprint and runtime overhead"?


Особенно смешно выглядит эта экономия на фоне
map.Add(new String(L"Zero"), new Integer(0));
map.Add(new String(L"One"), new Integer(1));
map.Add(new String(L"Two"), new Integer(2));

и
IMapEnumerator* pMapEnum = map.GetMapEnumeratorN();
delete pMapEnum;
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: это не Tizen 2.0!!!!
От: jazzer Россия Skype: enerjazzer
Дата: 21.02.13 01:49
Оценка:
Здравствуйте, niXman, Вы писали:

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


C>>А при чем здесь Tizen? Ваш eao197 просто не в теме. Самсунг как и обещал еще в прошлом году, добавил поддержку апи Бады.

C>>Сравните:
C>>здесь tizen
C>>и
C>>здесь бада
X>я не уверен, что из этого хуже %)
"Оба хуже" (с)

Второе очевидно хуже.
В первом по крайней мере честно просят передавать указатели, и хранят тоже указатели.
А во втором принимают константные ссылки, которые могут указывать на что угодно, в том числе и на временные объекты.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[13]: Вот еще, или я, кажется, читать разучился
От: niXman Ниоткуда https://github.com/niXman
Дата: 21.02.13 04:30
Оценка:
MTD, Evgeny.Panasyuk, осталось понять, что является истинной причиной некоторых, отказ от использования исключений. ибо я сомневаюсь, что причина отказа кроется в мегаоверхеде =)
в двух примерах, кстати, используются неоверхедные исключения(SEH & DWARF).
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[4]: Вот еще, или я, кажется, читать разучился
От: niXman Ниоткуда https://github.com/niXman
Дата: 21.02.13 04:31
Оценка: :)
Здравствуйте, landerhigh, Вы писали:

L>Я, кажется, знаю эту контору

что за контора?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[14]: Вот еще, или я, кажется, читать разучился
От: MTD https://github.com/mtrempoltsev
Дата: 21.02.13 05:05
Оценка: +1
Здравствуйте, niXman, Вы писали:

X>MTD, Evgeny.Panasyuk, осталось понять, что является истинной причиной некоторых, отказ от использования исключений. ибо я сомневаюсь, что причина отказа кроется в мегаоверхеде =)


Причины сугубо иррациональные. Контингент отказывающихся делится на две части:
1. Бородатые дядьки которые в начале 90-х попробовали С++ и обожглись, а теперь негативный опыт проецируют на сегодняшнее положение дел
2. Условно молодежь, которая смотря на авторитетов (бородатых дядек), подражает им не понимая причин
Re[15]: Вот еще, или я, кажется, читать разучился
От: niXman Ниоткуда https://github.com/niXman
Дата: 21.02.13 05:07
Оценка:
Здравствуйте, MTD, Вы писали:

MTD>1. Бородатые дядьки которые в начале 90-х попробовали С++ и обожглись, а теперь негативный опыт проецируют на сегодняшнее положение дел

а что, в начале 90-ых, с исключениями в с++ было не так?
(я тогда еще совсем сопливый был)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[16]: Вот еще, или я, кажется, читать разучился
От: MTD https://github.com/mtrempoltsev
Дата: 21.02.13 05:28
Оценка:
Здравствуйте, niXman, Вы писали:

X>а что, в начале 90-ых, с исключениями в с++ было не так?

X>(я тогда еще совсем сопливый был)

Да я тогда только в школе учился, поэтому знаю только со слов бородатых дядек Язык еще не устоялся, программировать на нем никто не умел, компиляторы были глючные и т.д. Читал у Спольски, что команда Экселя написала свой компилятор С++, чтобы юзать шаблоны.
Re[5]: Вот еще, или я, кажется, читать разучился
От: landerhigh Пират  
Дата: 21.02.13 05:32
Оценка:
Здравствуйте, niXman, Вы писали:

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


L>>Я, кажется, знаю эту контору

X>что за контора?

Да есть одна такая. На букву Г как раз.
www.blinnov.com
Re[17]: Вот еще, или я, кажется, читать разучился
От: niXman Ниоткуда https://github.com/niXman
Дата: 21.02.13 06:08
Оценка:
Здравствуйте, MTD, Вы писали:

MTD>Да я тогда только в школе учился, поэтому знаю только со слов бородатых дядек Язык еще не устоялся, программировать на нем никто не умел, компиляторы были глючные и т.д. Читал у Спольски, что команда Экселя написала свой компилятор С++, чтобы юзать шаблоны.


впервые, Си я потрогал в 99ом, на Dell с i386+4MB памяти. это был borland turbo C-2.0 =)
в 97ом, тыкал бейсик, на этом %)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[6]: Вот еще, или я, кажется, читать разучился
От: niXman Ниоткуда https://github.com/niXman
Дата: 21.02.13 06:10
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Да есть одна такая. На букву Г как раз.

понятно-понятно. не знал, что там тоже отказались от исключений. а говорят, что в Г работают только адекваты =)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[7]: Вот еще, или я, кажется, читать разучился
От: Ops Россия  
Дата: 21.02.13 06:39
Оценка:
Здравствуйте, niXman, Вы писали:

X>понятно-понятно. не знал, что там тоже отказались от исключений. а говорят, что в Г работают только адекваты =)


http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
ОФФ видимо)
От: Figaro Россия  
Дата: 21.02.13 07:46
Оценка:
Да вообще-то был еще Turbo 1.0, не хочу лезть в инет, но кажется его увидел в 1990, а с 1991 уже использовал Turbo C 2.0... Сишку на PDP увидел впервые году эдак в 1987 (15 лет было)... но это лично мое, можно много вспомнить и из жизни с ЕС-ок, там и фортран и Пролог и Паскакаль... Но плюсы только опосля Борланда 3.1 пользовал... Ностальджи..
avalon/1.0.432
Re: ОФФ видимо)
От: niXman Ниоткуда https://github.com/niXman
Дата: 21.02.13 07:48
Оценка:
Здравствуйте, Figaro, Вы писали:

F>Но плюсы только опосля Борланда 3.1 пользовал

плюсы я с ним и учил.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[7]: Вот еще, или я, кажется, читать разучился
От: Vzhyk  
Дата: 21.02.13 07:56
Оценка:
On 21.02.2013 9:10, niXman wrote:

> понятно-понятно. не знал, что там тоже отказались от исключений. а

> говорят, что в Г работают только адекваты =)
Хуже, что потом безумное количество начальников начинают подражать им и
требовать такое же в коде от подчиненных.
Posted via RSDN NNTP Server 2.1 beta
Re[8]: Вот еще, или я, кажется, читать разучился
От: jazzer Россия Skype: enerjazzer
Дата: 21.02.13 08:19
Оценка:
Здравствуйте, Ops, Вы писали:

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


X>>понятно-понятно. не знал, что там тоже отказались от исключений. а говорят, что в Г работают только адекваты =)


Ops>http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml


http://www.rsdn.ru/forum/cpp/4621115.1
Автор: jazzer
Дата: 16.02.12
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: Tizen 2.0
От: enji  
Дата: 21.02.13 09:19
Оценка:
Здравствуйте, niXman, Вы писали:

E>>(или как это правильно называется)

X>гетерогенные?
именно

X>на яве я не писатель, но от описанной тобою идеалогии становится непонятно, почему на фоне ява, с++ считается "опасным" ЯП %)


Потому что в яве все касты проверяются в рантайме и в описанной мной ситуации просто вылетит исключение. В С++ же будет UB — загажена память, произойдет вызов по нулевому адресу или еще какие страшности
Re[4]: Tizen 2.0
От: enji  
Дата: 21.02.13 09:22
Оценка:
Здравствуйте, Jack128, Вы писали:

J>как ты туда запихнешь int, если контейнер без шаблонов параметром Object* принимает??


никак. Поэтому int упаковывается в Integer, собственно как оно и происходит в C# / яве...

Но собственно что это меняет?

map.Add(new String(L"Two"), new Integer(2));     

String*    pValue = static_cast< String* > (map.GetValue(String(L"Zero"))); 

pValue->length(); // тут все плохо...
Re[5]: Tizen 2.0
От: enji  
Дата: 21.02.13 09:24
Оценка:
Здравствуйте, Jack128, Вы писали:


J>то что в плюсах выделенная строчка компилируется — это именно плюсовый касяк. но мне либо dynamic_cast либо reinterpret_cast.


тут просто дело в том, что static_cast разрешен от void* к любому указателю. Кстати dynamic_cast для указателя возвращает 0 при ошибке, и если ты это не проверишь перед использованием — будет ровно такое же UB, что и при static_cast
Re[14]: Вот еще, или я, кажется, читать разучился
От: enji  
Дата: 21.02.13 09:37
Оценка:
Здравствуйте, niXman, Вы писали:

X>MTD, Evgeny.Panasyuk, осталось понять, что является истинной причиной некоторых, отказ от использования исключений. ибо я сомневаюсь, что причина отказа кроется в мегаоверхеде =)

X>в двух примерах, кстати, используются неоверхедные исключения(SEH & DWARF).

Ну например некоторые компилеры их не поддерживают. Также имеет место оверхед по размеру программы, для МК-шек иногда важно...
Re[15]: Вот еще, или я, кажется, читать разучился
От: Vzhyk  
Дата: 21.02.13 09:49
Оценка:
On 21.02.2013 12:37, enji wrote:

> Ну например некоторые компилеры их не поддерживают. Также имеет место

> оверхед по размеру программы, для МК-шек иногда важно...
Кстати, а 8048 еще используется?
Posted via RSDN NNTP Server 2.1 beta
Re[15]: Вот еще, или я, кажется, читать разучился
От: niXman Ниоткуда https://github.com/niXman
Дата: 21.02.13 10:04
Оценка:
Здравствуйте, enji, Вы писали:

E>Ну например некоторые компилеры их не поддерживают.

ну..микрософтстудия не поддерживает DWARF, ибо ей не за чем. зато mingw-x86_64 поддерживает SEH.

я это к тому, что какие компиляторы могут использоваться для адроида и тизена, которые не поддерживают DWARF? мне такие не известны.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[15]: Вот еще, или я, кажется, читать разучился
От: landerhigh Пират  
Дата: 21.02.13 11:25
Оценка:
Здравствуйте, enji, Вы писали:

X>>в двух примерах, кстати, используются неоверхедные исключения(SEH & DWARF).


E>Ну например некоторые компилеры их не поддерживают. Также имеет место оверхед по размеру программы, для МК-шек иногда важно...


Например, gcc-avr. Только AVR-ы, для которых собирается код, имеют 1024 килобайта оперативки, а то и меньше, и там много чего еще нет. Например, new тоже обычно отключено (да и некуда его, этот new, делать). Впрочем, задачи, решаемые микроконтроллерами, редко требуют выхода из многократно вложенного блока по ошибке. Кстати, как раз на u-контроллерах исключительные ситуации можно обрабатывать исключительно — jmp <где тут у нас загрузчик>
www.blinnov.com
Re[16]: Вот еще, или я, кажется, читать разучился
От: niXman Ниоткуда https://github.com/niXman
Дата: 21.02.13 11:30
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Например, gcc-avr.

с микроконтроллерами понятно. но речь ведь про андроид и тизен.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[17]: Вот еще, или я, кажется, читать разучился
От: landerhigh Пират  
Дата: 21.02.13 11:51
Оценка:
Здравствуйте, niXman, Вы писали:

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


L>>Например, gcc-avr.

X>с микроконтроллерами понятно. но речь ведь про андроид и тизен.

У железок, на которых работает андроид и тизен, оперативки больше, чем объем жесткого диска на моем первом компьютере. О каком оверхеде тут можно вообще говорить —
www.blinnov.com
Re[16]: Вот еще, или я, кажется, читать разучился
От: Evgeny.Panasyuk Россия  
Дата: 21.02.13 12:10
Оценка:
Здравствуйте, niXman, Вы писали:

MTD>>1. Бородатые дядьки которые в начале 90-х попробовали С++ и обожглись, а теперь негативный опыт проецируют на сегодняшнее положение дел

X>а что, в начале 90-ых, с исключениями в с++ было не так?
X>(я тогда еще совсем сопливый был)

Их просто не было. Появились где-то в 1992, ранее были только эксперименты.
Re[7]: Вот еще, или я, кажется, читать разучился
От: landerhigh Пират  
Дата: 21.02.13 12:48
Оценка:
Здравствуйте, niXman, Вы писали:

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


L>>Да есть одна такая. На букву Г как раз.

X>понятно-понятно. не знал, что там тоже отказались от исключений. а говорят, что в Г работают только адекваты =)

Адекваты, как и в любом стартапе, там были в самом начале. Сейчас это, похоже, обычное корпоративное гнездо взвешивателей гномиков.
www.blinnov.com
Re[17]: Вот еще, или я, кажется, читать разучился
От: pzhy  
Дата: 21.02.13 16:33
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Их просто не было. Появились где-то в 1992, ранее были только эксперименты.


Есть еще момент того — что, часто эксперты в предметной области железа, оперируют в работе только логикой работы железа. Для этого хорош С но С++ уже некая "ненужная" абстракция. Я в эмбедед тоже поработал — и хочу сказать, это хорошая практика там. Кроме того на многих контроллерах С++ до сих пор сильно урезан. Кода там обычно мало — но "ответственность" больше. Поэтому на каждой операции проверка — норма, а вот исключение с потерей контекста — уже хуже ложится в логику.
Re[9]: Вот еще, или я, кажется, читать разучился
От: alex_public  
Дата: 21.02.13 16:34
Оценка: :)
Здравствуйте, jazzer, Вы писали:

J>http://www.rsdn.ru/forum/cpp/4621115.1
Автор: jazzer
Дата: 16.02.12


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

Да, но остальные ужасы из обсуждаемого примера это конечно же совсем не оправдывает. )))
Re[10]: Вот еще, или я, кажется, читать разучился
От: niXman Ниоткуда https://github.com/niXman
Дата: 21.02.13 16:38
Оценка:
Здравствуйте, alex_public, Вы писали:

_>я тоже считаю отказ от исключений хорошей практикой. И вроде никто так и не смог опровергнуть его. )))

хоть номер страницы укажи. их же там 25! %)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[18]: Вот еще, или я, кажется, читать разучился
От: Evgeny.Panasyuk Россия  
Дата: 21.02.13 16:51
Оценка:
Здравствуйте, pzhy, Вы писали:

P>Есть еще момент того — что, часто эксперты в предметной области железа, оперируют в работе только логикой работы железа. Для этого хорош С но С++ уже некая "ненужная" абстракция. Я в эмбедед тоже поработал — и хочу сказать, это хорошая практика там.


embedded — это отдельная тема (точно также как и kernel, mission-critical, etc), там накладываются свои ограничения, которые есть и для C и для C++.
Но несмотря на это, даже в 8-ми битниках, при правилом использовании C++ приносит пользу (при наличии компилятора), например.
Да, и не нужно забывать, что в C++ многие механизмы абстракции вообще бесплатны.
Re[10]: Вот еще, или я, кажется, читать разучился
От: MTD https://github.com/mtrempoltsev
Дата: 21.02.13 17:01
Оценка: 8 (3) +4 :))) :))
Здравствуйте, alex_public, Вы писали:

_>Ага, ага, помним эту темку... Там ещё дальше есть моё обоснование почему я тоже считаю отказ от исключений хорошей практикой. И вроде никто так и не смог опровергнуть его. )))


Это?

Ну вот собственно я и прошу (тех, кто уверен что исключения — это всегда лучше) показать подходящий юзкейс правильного использования, когда оно улучшило архитектуру или уменьшило объём кода. Потом хочу прикинуть как бы я это сделал без исключений и сравнить объём/читаемость...


Вот из Adobe Illustrator SDK, обрати внимание, как в середине чуваки сами запарились проверять код возврата и тупо забили на обработку ошибок:

ASErr EmptyPanelPlugin::StartupPlugin(SPInterfaceMessage *message)
{
    AIErr err = kNoErr;
    
    // Call base class routine
    err = Plugin::StartupPlugin(message);
    if (err)
        return err;

    AINotifierHandle appShutDownNotifier;
    err = sAINotifier->AddNotifier(fPluginRef, "AI Application Shutdown Notifier", kAIApplicationShutdownNotifier, &appShutDownNotifier);
    if(err)
        return err;
    
    AIErr error = kNoErr;

    // Add About Plugins menu item for this plug-in.
    SDKAboutPluginsHelper aboutPluginsHelper;
    error = aboutPluginsHelper.AddAboutPluginsMenuItem(message, 
                kSDKDefAboutSDKCompanyPluginsGroupName, 
                ai::UnicodeString(kSDKDefAboutSDKCompanyPluginsGroupNameString), 
                "EmptyPanel...", 
                &fAboutPluginMenu);

    if (error)
        return error;

    // Add menu item
    error = sAIMenu->AddMenuItemZString(fPluginRef, "Third Party Panel", kOtherPalettesMenuGroup, ZREF("Third Party Panel"),
                                        kMenuItemNoOptions, &fEmptyPanelPanelMenuItemHandle);
    if (error)
        return error;

    fPanelFlyoutMenu = NULL;
    error = sAIPanelFlyoutMenu->Create(fPanelFlyoutMenu);
    if (error)
        return error;

    error = sAIPanelFlyoutMenu->AppendItem(fPanelFlyoutMenu, 1, ai::UnicodeString("First Item"));
    error = sAIPanelFlyoutMenu->AppendItem(fPanelFlyoutMenu, 3, ai::UnicodeString("Third Item"));
    error = sAIPanelFlyoutMenu->InsertItem(fPanelFlyoutMenu, 3, 2, ai::UnicodeString("Second Item"));
    error = sAIPanelFlyoutMenu->InsertSeparator(fPanelFlyoutMenu, 3, 5);
    error = sAIPanelFlyoutMenu->AppendItem(fPanelFlyoutMenu, 4, ai::UnicodeString("Fourth Item"));

    error = sAIPanelFlyoutMenu->SetItemEnabled(fPanelFlyoutMenu, 4, false);
    error = sAIPanelFlyoutMenu->SetItemMark(fPanelFlyoutMenu, 1 , kAIPanelFlyoutMenuItemMark_BULLET);
    error = sAIPanelFlyoutMenu->SetItemMark(fPanelFlyoutMenu, 2 , kAIPanelFlyoutMenuItemMark_CHECK);
    error = sAIPanelFlyoutMenu->SetItemMark(fPanelFlyoutMenu, 3 , kAIPanelFlyoutMenuItemMark_DASH);

    AISize pnSize = {240, 320};
    error = sAIPanel->Create(fPluginRef, ai::UnicodeString("Third Party Panel"), ai::UnicodeString("Third Party Panel"), 3, pnSize, true, fPanelFlyoutMenu, this, fPanel);
    if (error)
        return error;

    AISize minSize = {50, 50};
    AISize maxSize = {800, 800};
    AISize prefConstSize = {100, 100};
    AISize prefUnconstSize = {600, 600};

    error = sAIPanel->SetSizes(fPanel, minSize, prefUnconstSize, prefConstSize, maxSize);

    error = sAIPanel->Show(fPanel, true);
    error = sAIPanel->SetFlyoutMenuPreVisibilityProc(fPanel, flyoutMenuPreVisFunc);
    error = sAIPanel->SetFlyoutMenuProc(fPanel, PanelFlyoutMenuProc);
    error = sAIPanel->SetVisibilityChangedNotifyProc(fPanel, PanelVisibilityChangedNotifyProc);
    error = sAIPanel->SetSizeChangedNotifyProc(fPanel, PanelSizeChangedNotifyProc);
    error = sAIPanel->SetStateChangedNotifyProc(fPanel, PanelStateChangedNotifyProc);
    error = sAIPanel->SetClosedNotifyProc(fPanel, PanelClosedNotifyProc);

    error = SetIcon();

    error = AddWidgets();
    
    //Add Menu Item for Control Bar
    if(!error)
        error = sAIMenu->AddMenuItemZString(fPluginRef, "Third Party Control Bar", kOtherPalettesMenuGroup, ZREF("Third Party Control Bar"),
                                            kMenuItemNoOptions, &fEmptyPanelControlBarMenuItemHandle);
    
    //Create Control Bar
    AISize sizeControlBar = {controlBarWidth, controlBarHeight};
    if(!error)
        error = sAIControlBar->Create(fPluginRef, sizeControlBar, controlBarWidthMin, controlBarWidthMax,NULL/*Userdata*/,fControlBar);
    if(!error)
        error = sAIControlBar->SetUserData(fControlBar, this);
    
    //Set Callbacks
    if(!error)
        error = sAIControlBar->SetVisibilityChangedNotifyProc(fControlBar, ControlBarVisibilityChangedNotifyProc);
    if(!error)
        error = sAIControlBar->SetSizeChangedNotifyProc(fControlBar, ControlBarSizeChangedNotifyProc);
    
    //Add Different Widgets to Control Bar
    if(!error)
        AddWidgetsToControlBar();
    
    return error;
}
Re[19]: Вот еще, или я, кажется, читать разучился
От: pzhy  
Дата: 21.02.13 17:14
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>embedded — это отдельная тема (точно также как и kernel, mission-critical, etc), там накладываются свои ограничения, которые есть и для C и для C++.

EP>Но несмотря на это, даже в 8-ми битниках, при правилом использовании C++ приносит пользу (при наличии компилятора), например.
EP>Да, и не нужно забывать, что в C++ многие механизмы абстракции вообще бесплатны.

Согласен что бесплатны (если они есть), но часто бесполезны. Если после каждой операции проверять ее результат — то исключения — просто синтаксический оверхед. А там именно так и пишут. Ну вот сам посуди, что можно сделать с исключением в такой ситуации в стэке выше? Сомоубиться — но в реальности есть много способов — но почти никогда на стэке выше уже ничего. Такова специфика. Поэтому и пишут так. И просто С с классами вроде и неплохо для РАИИ, но всегда найдется тот кто начнет применять там ненужный оверхед.
Re[11]: Вот еще, или я, кажется, читать разучился
От: alex_public  
Дата: 21.02.13 17:15
Оценка:
Здравствуйте, niXman, Вы писали:

_>>я тоже считаю отказ от исключений хорошей практикой. И вроде никто так и не смог опровергнуть его. )))

X>хоть номер страницы укажи. их же там 25! %)

Нуу началось кажется на 10-ой странице, а итог был подведён на 13-ой.

Хотя на самом деле я не против исключений именно для обработки критических ошибок (т.е. грубо говоря один try на всю программку и соответствующие исключения). Но чаще всего если их уж используют, то для обработки всех видов ошибок вообще. А это уже бред — они были созданы для другого! Так что проще запретить вообще, как Гугл и сделали.

Кстати, в контексте обсуждения данного примера, как я понимаю некоторые ожидали от tizen api как раз использования исключений для всего...
Re[19]: Вот еще, или я, кажется, читать разучился
От: alex_public  
Дата: 21.02.13 17:16
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>embedded — это отдельная тема (точно также как и kernel, mission-critical, etc), там накладываются свои ограничения, которые есть и для C и для C++.

EP>Но несмотря на это, даже в 8-ми битниках, при правилом использовании C++ приносит пользу (при наличии компилятора), например.
EP>Да, и не нужно забывать, что в C++ многие механизмы абстракции вообще бесплатны.

Ага) Я тоже предпочитаю C++ в микроконтроллерах. И кстати для тех, которые использую я, компиляторы C++ уже могут практически всё.
Re[11]: Вот еще, или я, кажется, читать разучился
От: alex_public  
Дата: 21.02.13 17:20
Оценка:
Здравствуйте, MTD, Вы писали:

MTD>Это?


MTD>

MTD>Ну вот собственно я и прошу (тех, кто уверен что исключения — это всегда лучше) показать подходящий юзкейс правильного использования, когда оно улучшило архитектуру или уменьшило объём кода. Потом хочу прикинуть как бы я это сделал без исключений и сравнить объём/читаемость...


MTD>Вот из Adobe Illustrator SDK, обрати внимание, как в середине чуваки сами запарились проверять код возврата и тупо забили на обработку ошибок:


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

Ну и это было только начало дискуссии — там дальше были и примеры)
Re[11]: Вот еще, или я, кажется, читать разучился
От: alex_public  
Дата: 21.02.13 17:25
Оценка:
Здравствуйте, MTD, Вы писали:

MTD>Вот из Adobe Illustrator SDK, обрати внимание, как в середине чуваки сами запарились проверять код возврата и тупо забили на обработку ошибок:


Посмотрел повнимательнее на ваш код... Ха, так это же как раз отличный пример того, о чём я говорил. Именно реализация такой логики (зря вы подумали что они забили в середине — это же очевидно логика такая) как раз и очень неудобна с помощью исключений.
Re[2]: это не Tizen 2.0!!!!
От: johny5 Новая Зеландия
Дата: 21.02.13 17:54
Оценка:
Здравствуйте, cencio, Вы писали:

C>А при чем здесь Tizen? Ваш eao197 просто не в теме. Самсунг как и обещал еще в прошлом году, добавил поддержку апи Бады.

C>Сравните:
C>здесь tizen
C>и
C>здесь бада

В Самсунге сидят такие быдлокодеры — вам и не снились.. (инсайдерская инфа).

В Интеле, видимо, получше, но не везде (наблюдения извне).
Re[12]: Вот еще, или я, кажется, читать разучился
От: Evgeny.Panasyuk Россия  
Дата: 21.02.13 18:56
Оценка:
Здравствуйте, alex_public, Вы писали:

MTD>>Вот из Adobe Illustrator SDK, обрати внимание, как в середине чуваки сами запарились проверять код возврата и тупо забили на обработку ошибок:


_>Посмотрел повнимательнее на ваш код... Ха, так это же как раз отличный пример того, о чём я говорил. Именно реализация такой логики (зря вы подумали что они забили в середине — это же очевидно логика такая) как раз и очень неудобна с помощью исключений.


Объясни, какая именно тут логика:
error = sAIPanel->Show(fPanel, true);
error = sAIPanel->SetFlyoutMenuPreVisibilityProc(fPanel, flyoutMenuPreVisFunc);
error = sAIPanel->SetFlyoutMenuProc(fPanel, PanelFlyoutMenuProc);
error = sAIPanel->SetVisibilityChangedNotifyProc(fPanel, PanelVisibilityChangedNotifyProc);
error = sAIPanel->SetSizeChangedNotifyProc(fPanel, PanelSizeChangedNotifyProc);
error = sAIPanel->SetStateChangedNotifyProc(fPanel, PanelStateChangedNotifyProc);
error = sAIPanel->SetClosedNotifyProc(fPanel, PanelClosedNotifyProc);

?
Чем это, отличается от например (предполагая что даже если operator= переопределён, то у него "обычная" семантика):
sAIPanel->Show(fPanel, true);
sAIPanel->SetFlyoutMenuPreVisibilityProc(fPanel, flyoutMenuPreVisFunc);
sAIPanel->SetFlyoutMenuProc(fPanel, PanelFlyoutMenuProc);
sAIPanel->SetVisibilityChangedNotifyProc(fPanel, PanelVisibilityChangedNotifyProc);
sAIPanel->SetSizeChangedNotifyProc(fPanel, PanelSizeChangedNotifyProc);
sAIPanel->SetStateChangedNotifyProc(fPanel, PanelStateChangedNotifyProc);
error = sAIPanel->SetClosedNotifyProc(fPanel, PanelClosedNotifyProc);

?
Я согласен с MTD, это называется — "тупо забили".
Re[13]: Вот еще, или я, кажется, читать разучился
От: alex_public  
Дата: 21.02.13 19:04
Оценка: -7 :)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Объясни, какая именно тут логика:

EP>
EP>error = sAIPanel->Show(fPanel, true);
EP>error = sAIPanel->SetFlyoutMenuPreVisibilityProc(fPanel, flyoutMenuPreVisFunc);
EP>error = sAIPanel->SetFlyoutMenuProc(fPanel, PanelFlyoutMenuProc);
EP>error = sAIPanel->SetVisibilityChangedNotifyProc(fPanel, PanelVisibilityChangedNotifyProc);
EP>error = sAIPanel->SetSizeChangedNotifyProc(fPanel, PanelSizeChangedNotifyProc);
EP>error = sAIPanel->SetStateChangedNotifyProc(fPanel, PanelStateChangedNotifyProc);
EP>error = sAIPanel->SetClosedNotifyProc(fPanel, PanelClosedNotifyProc);
EP>

EP>?
EP>Чем это, отличается от например (предполагая что даже если operator= переопределён, то у него "обычная" семантика):
EP>
EP>sAIPanel->Show(fPanel, true);
EP>sAIPanel->SetFlyoutMenuPreVisibilityProc(fPanel, flyoutMenuPreVisFunc);
EP>sAIPanel->SetFlyoutMenuProc(fPanel, PanelFlyoutMenuProc);
EP>sAIPanel->SetVisibilityChangedNotifyProc(fPanel, PanelVisibilityChangedNotifyProc);
EP>sAIPanel->SetSizeChangedNotifyProc(fPanel, PanelSizeChangedNotifyProc);
EP>sAIPanel->SetStateChangedNotifyProc(fPanel, PanelStateChangedNotifyProc);
EP>error = sAIPanel->SetClosedNotifyProc(fPanel, PanelClosedNotifyProc);
EP>

EP>?
EP>Я согласен с MTD, это называется — "тупо забили".

Ну вы даёте... Очевидно же что в первом случае в error будет код ошибки (не важно какой, главное что ошибка) при возврате ошибки из любой из этих функций, а не только из последней. Да, и кстати после этого куска там как раз стоит код проверяющий этот факт с соответствующими действиями далее. Причём таких блока там целых 2, так что версия что "к середине функции устали и забили" звучит очень забавно конечно. )))
Re[20]: Вот еще, или я, кажется, читать разучился
От: Evgeny.Panasyuk Россия  
Дата: 21.02.13 19:06
Оценка: +1
Здравствуйте, pzhy, Вы писали:

EP>>Да, и не нужно забывать, что в C++ многие механизмы абстракции вообще бесплатны.


P>Согласен что бесплатны (если они есть), но часто бесполезны.


Почему? Они помогают сократить как код, так и нагрузку на "мозги" программистов.
IMHO, абстракции — это самое мощное оружие в арсенале разработчика.

P>Если после каждой операции проверять ее результат — то исключения — просто синтаксический оверхед.


Наоборот, if-error-goto на каждой операции это синтаксический overhead, от которого можно избавится с помощью исключений
Если же ты говоришь про использование исключений как return values — то я не вижу смысла в обсуждении патологических случаев.

P>А там именно так и пишут.


Где?

P>Ну вот сам посуди, что можно сделать с исключением в такой ситуации в стэке выше?


Тоже самое что и с error-code Если при использовании error-code он не передаётся "далеко" наверх, то и исключения можно обрабатывать "пониже".

P>Сомоубиться — но в реальности есть много способов — но почти никогда на стэке выше уже ничего. Такова специфика. Поэтому и пишут так.


Кто пишет? Где?

P>И просто С с классами вроде и неплохо для РАИИ, но всегда найдется тот кто начнет применять там ненужный оверхед.


Ты о чём?
Re[14]: Вот еще, или я, кажется, читать разучился
От: Evgeny.Panasyuk Россия  
Дата: 21.02.13 19:13
Оценка: 2 (2) +2
Здравствуйте, alex_public, Вы писали:

_>Ну вы даёте... Очевидно же что в первом случае в error будет код ошибки (не важно какой, главное что ошибка) при возврате ошибки из любой из этих функций, а не только из последней.


Это откуда следует? Там же = , а не |=
Re[12]: Вот еще, или я, кажется, читать разучился
От: Evgeny.Panasyuk Россия  
Дата: 21.02.13 19:31
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Хотя на самом деле я не против исключений именно для обработки критических ошибок (т.е. грубо говоря один try на всю программку и соответствующие исключения). Но чаще всего если их уж используют, то для обработки всех видов ошибок вообще. А это уже бред — они были созданы для другого!


Никто не заставляет использовать исключения для каждого вида ошибок, а тем более для return values.

_>Так что проще запретить вообще, как Гугл и сделали.


http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=Exceptions#Exceptions
То что ты выше описал Google относит к Cons:

The availability of exceptions may encourage developers to throw them when they are not appropriate or recover from them when it's not safe to do so. For example, invalid user input should not cause exceptions to be thrown. We would need to make the style guide even longer to document these restrictions!

Но решение было сделано на основе другого фактора:

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.

Period.
Re[2]: Tizen 2.0
От: ML380 Земля  
Дата: 21.02.13 20:30
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>

L>The object is not fully constructed after this constructor is called. For full construction,
L>the Construct() method must be called right after calling this constructor.


Интересно, а какие могут быть объекивные причины так делать? например.
Re[3]: Tizen 2.0
От: Evgeny.Panasyuk Россия  
Дата: 21.02.13 21:10
Оценка: 2 (1)
Здравствуйте, ML380, Вы писали:

L>>

L>>The object is not fully constructed after this constructor is called. For full construction,
L>>the Construct() method must be called right after calling this constructor.

ML>Интересно, а какие могут быть объекивные причины так делать? например.

Это делается скорей всего из-за бана исключений ( так же как и у Google ).
А вот почему у них исключения забанены —
Re[3]: Tizen 2.0
От: landerhigh Пират  
Дата: 22.02.13 00:33
Оценка: +1
Здравствуйте, ML380, Вы писали:

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


L>>

L>>The object is not fully constructed after this constructor is called. For full construction,
L>>the Construct() method must be called right after calling this constructor.


ML>Интересно, а какие могут быть объекивные причины так делать? например.


Если не рассматривать дурость с "исключения нельзя использовать, потом что мы на самом деле их ниасилили", то остается исчезающе мало причин. Например, когда объект по какой-то причине создается в один момент, но его инициализация должна произойти намного позже. Такой паттерн с методом Init иногда используется, но подобный ужас почти всегда можно вылечить банальнейшим IoC (фабрикой).
www.blinnov.com
Re[13]: Вот еще, или я, кажется, читать разучился
От: Vzhyk  
Дата: 22.02.13 08:21
Оценка:
On 21.02.2013 22:31, Evgeny.Panasyuk wrote:

> использовать исключения для return values.

Это как бы противоречит самому поняттию исключение?
Posted via RSDN NNTP Server 2.1 beta
Re[16]: Вот еще, или я, кажется, читать разучился
От: enji  
Дата: 22.02.13 09:26
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Только AVR-ы, для которых собирается код, имеют 1024 килобайта оперативки,

avr-ки стока не имеют В самых толстых речь идет о 4-8 килобайтах...
Re[14]: Вот еще, или я, кажется, читать разучился
От: Evgeny.Panasyuk Россия  
Дата: 22.02.13 12:24
Оценка:
Здравствуйте, Vzhyk, Вы писали:

>> использовать исключения для return values.

V>Это как бы противоречит самому поняттию исключение?

Художественная резка по цитатам?

Никто не заставляет использовать исключения для каждого вида ошибок, а тем более для return values.


Вообще, речь шла про abuse.
Re[17]: Вот еще, или я, кажется, читать разучился
От: landerhigh Пират  
Дата: 22.02.13 12:51
Оценка:
Здравствуйте, enji, Вы писали:

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


L>>Только AVR-ы, для которых собирается код, имеют 1024 килобайта оперативки,

E>avr-ки стока не имеют В самых толстых речь идет о 4-8 килобайтах...

Вообще-то самая популярная Atmega328 имеет целых 2 килобайта. Тут можно разугляться!
www.blinnov.com
Re[15]: Вот еще, или я, кажется, читать разучился
От: Vzhyk  
Дата: 22.02.13 14:11
Оценка:
On 22.02.2013 15:24, Evgeny.Panasyuk wrote:

> Художественная резка по цитатам?

Нет, я не спорил с тобой. Я просто удивился, зачем использовать таким
странным образом то, что для этого не предназначено.
Posted via RSDN NNTP Server 2.1 beta
Re[15]: Вот еще, или я, кажется, читать разучился
От: alex_public  
Дата: 22.02.13 15:37
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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


_>>Ну вы даёте... Очевидно же что в первом случае в error будет код ошибки (не важно какой, главное что ошибка) при возврате ошибки из любой из этих функций, а не только из последней.


EP>Это откуда следует? Там же = , а не |=


Ааа мой косяк, проглядел))) Уже в полусне писал и показалось))) Тогда действительно сомнительный код у них там. Что впрочем никак не влияет на нашу основную дискуссию. )
Re[13]: Вот еще, или я, кажется, читать разучился
От: alex_public  
Дата: 22.02.13 15:45
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Никто не заставляет использовать исключения для каждого вида ошибок, а тем более для return values.


Ну так в контексте обсуждения Tizen api как раз было ближе к реализации замены кодов ошибок на исключения.

Да, кстати, но вот одну вещь я на самом деле не очень понял. Почему следствием отказа от исключений является обязательное наличие двухшаговой инициализации всех объектов? У нас вот исключения в таких случаях не используются, но и потребности в такой инициализации что-то не припомню...

EP>http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=Exceptions#Exceptions

EP>То что ты выше описал Google относит к Cons:
EP>Но решение было сделано на основе другого фактора:
EP>Period.

Ну так я свою точку зрения высказываю. При этом выходит так что она частично пересекается с гугловскими. )
Re[14]: Вот еще, или я, кажется, читать разучился
От: Evgeny.Panasyuk Россия  
Дата: 22.02.13 17:45
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Да, кстати, но вот одну вещь я на самом деле не очень понял. Почему следствием отказа от исключений является обязательное наличие двухшаговой инициализации всех объектов? У нас вот исключения в таких случаях не используются, но и потребности в такой инициализации что-то не припомню...


В нормальной ситуации, когда конструктор не может установить нужные инварианты объекта, не может нормально создать объект — он кидает исключение.
При таком подходе нету места "частично созданным" объектам, так как по правилам языка если из конструктора вылетает исключение, то нет возможности что-либо с ним сделать (не будем рассматривать патологические случаи ковыряния в raw bytes of dead object).

Например, что ты будешь делать без исключений в следующем случае?:
{
    vector<int> v(16); // may fail on allocation
    cout << v[0];
}

Приведи аналогичный код(клиентскую часть), но без использования исключений.
Re[15]: Вот еще, или я, кажется, читать разучился
От: alex_public  
Дата: 23.02.13 04:01
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

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

EP>При таком подходе нету места "частично созданным" объектам, так как по правилам языка если из конструктора вылетает исключение, то нет возможности что-либо с ним сделать (не будем рассматривать патологические случаи ковыряния в raw bytes of dead object).

EP>Например, что ты будешь делать без исключений в следующем случае?:

EP>
EP>{
EP>    vector<int> v(16); // may fail on allocation
EP>    cout << v[0];
EP>}
EP>

EP>Приведи аналогичный код(клиентскую часть), но без использования исключений.

Ну так это как раз редкий пример оправданного применения исключений, т.к. в большинстве случаев при ошибке выделения памяти остаётся только корректно самоуничтожиться. ))) Но это у нас исключение из стандартной библиотеки, а не в нашем коде. Речь то шла о своих... )
Re[16]: Вот еще, или я, кажется, читать разучился
От: Evgeny.Panasyuk Россия  
Дата: 23.02.13 04:29
Оценка:
Здравствуйте, alex_public, Вы писали:

EP>>Например, что ты будешь делать без исключений в следующем случае?:

EP>>
EP>>{
EP>>    vector<int> v(16); // may fail on allocation
EP>>    cout << v[0];
EP>>}
EP>>

EP>>Приведи аналогичный код(клиентскую часть), но без использования исключений.
_>Ну так это как раз редкий пример оправданного применения исключений, т.к. в большинстве случаев при ошибке выделения памяти остаётся только корректно самоуничтожиться. )))

Редкий?
Выделение памяти в приложении, внутри структур данных — это редкость?

_>Но это у нас исключение из стандартной библиотеки, а не в нашем коде. Речь то шла о своих... )


struct MyStruct
{
    vector<int> v;
    // ...
    MyStruct()
        : v(16)
    {}
};
// ...
{
    MyStruct m;
}



или например:
class Percent
{
    double p;
public:
    explicit Percent(double p_)
        : p(p_)
    {
        if( (p > 100.0) || (p<0.0) )
            throw domain_error("Wrong Percent");
    }
    double value() const
    {
        return p;
    }
};
// ...
{
    Percent p(user_input_from_upper_layers);
}

Re[16]: Вот еще, или я, кажется, читать разучился
От: jazzer Россия Skype: enerjazzer
Дата: 23.02.13 07:50
Оценка: 11 (2) +1
Здравствуйте, alex_public, Вы писали:

_>Тогда действительно сомнительный код у них там. Что впрочем никак не влияет на нашу основную дискуссию. )


Не влияет? Тут народ прямиком забивает на обработку ошибок, и это называется — не влияет? Это как раз отличная демонстрация безопасности так называемой "обработки" ошибок через коды возврата.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[17]: Вот еще, или я, кажется, читать разучился
От: alex_public  
Дата: 23.02.13 18:21
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Редкий?

EP>Выделение памяти в приложении, внутри структур данных — это редкость?

Редким является не выделения памяти, а ситуация когда оно даёт сбой. И из факта особенности этой ситуации следуют соответствующие выводы насчёт её обработки...
Re[17]: Вот еще, или я, кажется, читать разучился
От: alex_public  
Дата: 23.02.13 18:24
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Не влияет? Тут народ прямиком забивает на обработку ошибок, и это называется — не влияет? Это как раз отличная демонстрация безопасности так называемой "обработки" ошибок через коды возврата.


Ну так для правильности таких выводов надо всего лишь показать что вариант этого кода через исключения намного короче и удобнее...
Re[15]: Вот еще, или я, кажется, читать разучился
От: landerhigh Пират  
Дата: 23.02.13 19:18
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Например, что ты будешь делать без исключений в следующем случае?:

<skip>
EP>Приведи аналогичный код(клиентскую часть), но без использования исключений.

Меня больше интересует, как разработчики Tizen собираются сообщать о том, что конструктор копирования обломался? Похоже, этот фреймворк, как говорится, fundamentaly flawed.
www.blinnov.com
Re[16]: Вот еще, или я, кажется, читать разучился
От: Evgeny.Panasyuk Россия  
Дата: 23.02.13 21:02
Оценка:
Здравствуйте, landerhigh, Вы писали:

EP>>Например, что ты будешь делать без исключений в следующем случае?:

L><skip>
EP>>Приведи аналогичный код(клиентскую часть), но без использования исключений.
L>Меня больше интересует, как разработчики Tizen собираются сообщать о том, что конструктор копирования обломался? Похоже, этот фреймворк, как говорится, fundamentaly flawed.

Видимо вот так:
result     HashMap::Construct (const IMap &map, float loadFactor=0.75)

Вот только я по докам не вижу чтобы у них обычный copy constructor был забанен(либо как-то реализован).
У всемогущего Object'а он protected, но вот реализован он или нет —
Tizen::Base::Object::Object (const Object &obj) [protected]
//This is the copy constructor for the Object class.

Раз protected — то по-идеи реализован, иначе было бы просто private (compiler error лучше чем linker error).
Если у кого-нибудь есть .h — что там за layout у HashMap?
Re[18]: Вот еще, или я, кажется, читать разучился
От: jazzer Россия Skype: enerjazzer
Дата: 24.02.13 05:36
Оценка:
Здравствуйте, alex_public, Вы писали:

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


J>>Не влияет? Тут народ прямиком забивает на обработку ошибок, и это называется — не влияет? Это как раз отличная демонстрация безопасности так называемой "обработки" ошибок через коды возврата.


_>Ну так для правильности таких выводов надо всего лишь показать что вариант этого кода через исключения намного короче и удобнее...


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

Ну и да, с исключениями игнорировать ошибки "короче и удобнее" не получится, вот ведь незадача.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[19]: Вот еще, или я, кажется, читать разучился
От: alex_public  
Дата: 24.02.13 10:55
Оценка:
Здравствуйте, jazzer, Вы писали:

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


Кривой код можно найти под любую идею/технологию/платформу. Но это ничего не доказывает.

J>Ну и да, с исключениями игнорировать ошибки "короче и удобнее" не получится, вот ведь незадача.


Я правильно понял, что вы считаете нормальным использовать исключения для обработки всех видов ошибок?
Re[20]: Вот еще, или я, кажется, читать разучился
От: jazzer Россия Skype: enerjazzer
Дата: 24.02.13 12:55
Оценка: +3
Здравствуйте, alex_public, Вы писали:

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


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


_>Кривой код можно найти под любую идею/технологию/платформу. Но это ничего не доказывает.


Еще как доказывает. Есть такое понятие — error-prone. Не знаю, как правильно перевести, но смысл такой: приглашение совершить ошибку, легкость совершения ошибки.
Например, ручное управление памятью — error-prone.
Голые указатели — error-prone.
И обработка ошибок, построенная на кодах возврата — тоже error-prone, и обсуждаемый пример — замечательная тому иллюстрация.

J>>Ну и да, с исключениями игнорировать ошибки "короче и удобнее" не получится, вот ведь незадача.


_>Я правильно понял, что вы считаете нормальным использовать исключения для обработки всех видов ошибок?

Ошибок — да. Дальше можно порассуждать о том, что считать ошибкой.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[17]: Вот еще, или я, кажется, читать разучился
От: landerhigh Пират  
Дата: 24.02.13 15:07
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

L>>Меня больше интересует, как разработчики Tizen собираются сообщать о том, что конструктор копирования обломался? Похоже, этот фреймворк, как говорится, fundamentaly flawed.


EP>Видимо вот так:

EP>
EP>result     HashMap::Construct (const IMap &map, float loadFactor=0.75)
EP>

EP>Вот только я по докам не вижу чтобы у них обычный copy constructor был забанен(либо как-то реализован).

Хех. Забавно:

Дока от Base::String.

Copying of objects using this copy constructor is allowed.


Кажется, мы имеем дело с т.н. epic fail.
www.blinnov.com
Re[21]: Вот еще, или я, кажется, читать разучился
От: ioj Ниоткуда  
Дата: 24.02.13 15:55
Оценка: -2
Здравствуйте, jazzer, Вы писали:

Вы ( не вы лично, а все сторонники исключений в этом треде) вообще читаете что в гугловском документе написано?

When you add a throw statement to an existing function, you must examine all of its transitive callers. Either they must make at least the basic exception safety guarantee, or they must never catch the exception and be happy with the program terminating as a result. For instance, if f() calls g() calls h(), and h throws an exception that f catches, g has to be careful or it may not clean up properly.

Весь код должен обеспечивать basic exception safety, иначе любое исключение, брошенное например в середине метода, легко и непринуждённо может оставить объект в inconsistent состоянии, и я думаю обеспечить эту exception safety гораздо сложнее чем обеспечить проверку всех возвращаемых значений. Далее:

More generally, exceptions make the control flow of programs difficult to evaluate by looking at code: functions may return in places you don't expect. This causes maintainability and debugging difficulties. You can minimize this cost via some rules on how and where exceptions can be used, but at the cost of more that a developer needs to know and understand.


это проблема номер два ( хотя может и номер один по важности ) с исключениями — сторонний execution flow создаваемый исключениями, я уже не могу сказать глядя на код что между вот этими двумя строками не произошло исключение и мы не пошли вообще по другому call graph. К тому же в С++ нет finally, поэтому ту же basic exception safety обеспечивать весьма геморройно, даже если тотально всё заворачивать в raii обвёртки, и даже если бы finally таки было, всё равно you're forced to obfuscate code to isolate the commit:

Exception safety requires both RAII and different coding practices. Lots of supporting machinery is needed to make writing correct exception-safe code easy. Further, to avoid requiring readers to understand the entire call graph, exception-safe code must isolate logic that writes to persistent state into a "commit" phase. This will have both benefits and costs (perhaps where you're forced to obfuscate code to isolate the commit). Allowing exceptions would force us to always pay those costs even when they're not worth it.
нормально делай — нормально будет
Re[22]: Вот еще, или я, кажется, читать разучился
От: jazzer Россия Skype: enerjazzer
Дата: 24.02.13 16:55
Оценка: 19 (5) +3
Здравствуйте, ioj, Вы писали:

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


ioj>Вы ( не вы лично, а все сторонники исключений в этом треде) вообще читаете что в гугловском документе написано?


ioj>When you add a throw statement to an existing function, you must examine all of its transitive callers. Either they must make at least the basic exception safety guarantee, or they must never catch the exception and be happy with the program terminating as a result. For instance, if f() calls g() calls h(), and h throws an exception that f catches, g has to be careful or it may not clean up properly.


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

ioj>Весь код должен обеспечивать basic exception safety, иначе любое исключение, брошенное например в середине метода, легко и непринуждённо может оставить объект в inconsistent состоянии, и я думаю обеспечить эту exception safety гораздо сложнее чем обеспечить проверку всех возвращаемых значений.


Это противоречит моему опыту. Basic exception safety достигается элементарно.

ioj>Далее:

ioj>More generally, exceptions make the control flow of programs difficult to evaluate by looking at code: functions may return in places you don't expect. This causes maintainability and debugging difficulties. You can minimize this cost via some rules on how and where exceptions can be used, but at the cost of more that a developer needs to know and understand.
ioj>


Это все не нужно. "control flow of programs", написанных на исключениях (т.е. обеспечивающих по крайней мере базовую безопасность), анализировать как раз проще всего — они выполняются до конца или пока не вылетит исключение, причем не важно откуда (кроме nothrow-функций, естественно — они никогда ничего не должны бросать).
Причем и в том, и в другом случае нам не нужно совершать дополнительных телодвижений по очистке и прочему, так как RAIIза всем проследит автоматически.
Разница будет, только если мы хотим обеспечивать сильную безопасность, а у нас на руках только базовая.

ioj>это проблема номер два ( хотя может и номер один по важности ) с исключениями — сторонний execution flow создаваемый исключениями, я уже не могу сказать глядя на код что между вот этими двумя строками не произошло исключение и мы не пошли вообще по другому call graph.

И не надо. Код надо писать, имея в виду, что почти любая функция может бросить исключение. Т.е. тотальный RAII.

ioj>К тому же в С++ нет finally

И очень хорошо, что нету. Оставим finally недоязыкам типа Java, у которых нет RAII.

ioj>поэтому ту же basic exception safety обеспечивать весьма геморройно, даже если тотально всё заворачивать в raii обвёртки

Не имею никакого геморроя с RAII-обертками, что я делаю не так?

ioj>и даже если бы finally таки было, всё равно you're forced to obfuscate code to isolate the commit:

ioj>Exception safety requires both RAII and different coding practices. Lots of supporting machinery is needed to make writing correct exception-safe code easy. Further, to avoid requiring readers to understand the entire call graph, exception-safe code must isolate logic that writes to persistent state into a "commit" phase. This will have both benefits and costs (perhaps where you're forced to obfuscate code to isolate the commit). Allowing exceptions would force us to always pay those costs even when they're not worth it.

А тут мы плавно подменили basic exception safety на strong exception safety и сделали вид, что говорим об одном и том же — молодца!

"avoid requiring readers to understand the entire call graph" — нафиг никому не нужен the entire call graph. Потому что функция либо играет до конца, либо вылетает по ислючению. Всё.

Опять же, утверждение про obfuscate противоречит моему опыту. Классический пример реализации сильной безопасности, как раз с изолированием коммита, выглядит вот так:
A& A::operator=(A rhs) // временный объект (т.к. по значению)
{
  swap( rhs );         // коммит (nothrow)
  return this;
}

Где ты тут видишь obfuscate?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[22]: Вот еще, или я, кажется, читать разучился
От: enji  
Дата: 24.02.13 16:59
Оценка: 7 (1) +1
Здравствуйте, ioj, Вы писали:

ioj>Вы ( не вы лично, а все сторонники исключений в этом треде) вообще читаете что в гугловском документе написано?


ioj>When you add a throw statement to an existing function, you must examine all of its transitive callers. Either they must make at least the basic exception safety guarantee, or they must never catch the exception and be happy with the program terminating as a result. For instance, if f() calls g() calls h(), and h throws an exception that f catches, g has to be careful or it may not clean up properly.


ioj>Весь код должен обеспечивать basic exception safety, иначе любое исключение, брошенное например в середине метода, легко и непринуждённо может оставить объект в inconsistent состоянии, и я думаю обеспечить эту exception safety гораздо сложнее чем обеспечить проверку всех возвращаемых значений.


Думаешь? Ну так возвращаемые значения надо не только проверить, но и выполнить очистку, причем иногда очистка разная в зависимости от того, на каком именно этапе облом Собственно это ровно то же самое, что и с исключениями. Единственное — при ручной проверке кодов возврата ты видишь в коде места, где у тебя может случиться облом. А при исключениях — считаешь что он может случиться в любом месте. Поэтому когда пишут с "поддержкой" исключений, обычно используют автоматические техники — типа RAII или BOOST_SCOPED_EXIT. А вот когда пишут на кодах возврата — обычно делают вручную, что и приводит к багам, как в коде выше...

ioj>More generally, exceptions make the control flow of programs difficult to evaluate by looking at code: functions may return in places you don't expect. This causes maintainability and debugging difficulties. You can minimize this cost via some rules on how and where exceptions can be used, but at the cost of more that a developer needs to know and understand.

ioj>


ioj>это проблема номер два ( хотя может и номер один по важности ) с исключениями — сторонний execution flow создаваемый исключениями, я уже не могу сказать глядя на код что между вот этими двумя строками не произошло исключение и мы не пошли вообще по другому call graph.

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

ioj>К тому же в С++ нет finally, поэтому ту же basic exception safety обеспечивать весьма геморройно, даже если тотально всё заворачивать в raii обвёртки,

об отсутствии finally иногда жалею, но есть SCOPED_EXIT, а в частых случаях — готовые raii-обертки. Так что насчет геморройности не согласен.

ioj>и даже если бы finally таки было, всё равно you're forced to obfuscate code to isolate the commit:

Ты так говоришь, как будто с кодами возврата нет такой проблемы. Если ты сделал что-то изменяющее мир, а потом случилась ошибка — какая разница, код возврата это или исключение? Тебе надо или вернуть все назад или переработать метод, чтобы мир изменялся после всех потенциально-ошибочных операций...
Re[3]: это не Tizen 2.0!!!!
От: dr. Acula Украина  
Дата: 24.02.13 18:15
Оценка:
J>В Самсунге сидят такие быдлокодеры — вам и не снились.. (инсайдерская инфа).

А где не быдлокодеры сидят?
Можно списочек в студию?
Re[4]: это не Tizen 2.0!!!!
От: Vzhyk  
Дата: 24.02.13 18:29
Оценка: 1 (1)
On 24.02.2013 21:15, dr. Acula wrote:

> А где не быдлокодеры сидят?

> Можно списочек в студию?
Это секретная информация и никто ею с тобой не поделится. Откуда сидящие
там знают, что ты не "быдлокодер".
Posted via RSDN NNTP Server 2.1 beta
Re[21]: Вот еще, или я, кажется, читать разучился
От: alex_public  
Дата: 24.02.13 22:17
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Еще как доказывает. Есть такое понятие — error-prone. Не знаю, как правильно перевести, но смысл такой: приглашение совершить ошибку, легкость совершения ошибки.

J>Например, ручное управление памятью — error-prone.
J>Голые указатели — error-prone.
J>И обработка ошибок, построенная на кодах возврата — тоже error-prone, и обсуждаемый пример — замечательная тому иллюстрация.

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

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

_>>Я правильно понял, что вы считаете нормальным использовать исключения для обработки всех видов ошибок?

J>Ошибок — да. Дальше можно порассуждать о том, что считать ошибкой.

Нуу вот есть классический пример. Пользователь даёт команду сохранить данные в файл, а он оказывается заблокирован. Это как у нас считается?
Re[22]: Вот еще, или я, кажется, читать разучился
От: landerhigh Пират  
Дата: 25.02.13 01:37
Оценка: +2
Здравствуйте, alex_public, Вы писали:


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


Мое HO — данный конкретный пример как раз показывает, что такое исключительная ситуация. Плагин добавляет контролы. Если добавление какого-то контрола обламывается, то это именно исключительная ситуация без разговоров и самая правильная стратегия в данном случае — прекратить инициализацию вообще и не пытаться умничать. Никогда не встречали программы, которые при каких-либо сценариях выдавали по полторы сотни мессаджбоксов друг за другом, каждый с многозначительным сообщением типа "ошибка инициализации"?
Здесь исключение — наиболее натуральный вариант. Выход по первому error, в принципе, тоже сработает, но получился лес if-ов.

Кстати, из кода очевидно, что код этот никак не тестировался для негативного случая.
www.blinnov.com
Re[22]: Вот еще, или я, кажется, читать разучился
От: landerhigh Пират  
Дата: 25.02.13 01:39
Оценка: +2 :)
Здравствуйте, ioj, Вы писали:

ioj>Вы ( не вы лично, а все сторонники исключений в этом треде) вообще читаете что в гугловском документе написано?


Читали. Мое мнение — хорошо, что гугловских инженеров к Боингам подпускают только в качестве пассажиров.
www.blinnov.com
Re[23]: Вот еще, или я, кажется, читать разучился
От: Erop Россия  
Дата: 25.02.13 02:14
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Это противоречит моему опыту. Basic exception safety достигается элементарно.

Это говорит о том, что либо твоё "элементарно" -- это малодостижимый уровнь для типичного программиста, либо о том, что мы с тобой как-то по-разному, понимаем что такое "basic exception safety", либо ты не имеешь дела никогда со сложными структурами данных, либо ты лукавишь...

Я верно же понимаю, что под "basic exception safety" понимают гарантию того, что при вылете исключения, могут быть сторонние эффекты, но не могут нарушаться инварианты и не случится утечек?..

Если так, то в качестве примера, нарисуй нам горантирующий basic exception safety метод std::vector, который переаллоцирует буфер, и при этом поддерживает move-семантику соержимого...
Пусть у move-конструктора элемента тоже будет "basic exception safety", а у деструктора гарантия невылета...

J>Это все не нужно. "control flow of programs", написанных на исключениях (т.е. обеспечивающих по крайней мере базовую безопасность), анализировать как раз проще всего — они выполняются до конца или пока не вылетит исключение, причем не важно откуда (кроме nothrow-функций, естественно — они никогда ничего не должны бросать).

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

J>И не надо. Код надо писать, имея в виду, что почти любая функция может бросить исключение. Т.е. тотальный RAII.


Это вообще никак не гарантирует "basic exception safety"...
J>Не имею никакого геморроя с RAII-обертками, что я делаю не так?
Ты всё делаешь так.
Покажи нам мастер-класс, пожалуйста. На примере переаллокации буфера вектора, например

J>Опять же, утверждение про obfuscate противоречит моему опыту. Классический пример реализации сильной безопасности, как раз с изолированием коммита, выглядит вот так:

J>
J>A& A::operator=(A rhs) // временный объект (т.к. по значению)
J>{
J>  swap( rhs );         // коммит (nothrow)
J>  return this;
J>}
J>

J>Где ты тут видишь obfuscate?

Теперь давай напишем структуру, поля которой -- A.
Для неё как будем сильную безопасность обеспечивать?..

А теперь небольшую базу данных (метров на триста, например), в памяти...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[24]: Вот еще, или я, кажется, читать разучился
От: landerhigh Пират  
Дата: 25.02.13 03:43
Оценка: :)
Здравствуйте, Erop, Вы писали:

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


J>>Это противоречит моему опыту. Basic exception safety достигается элементарно.

E>Это говорит о том, что либо твоё "элементарно" -- это малодостижимый уровнь для типичного программиста, либо о том, что мы с тобой как-то по-разному, понимаем что такое "basic exception safety", либо ты не имеешь дела никогда со сложными структурами данных, либо ты лукавишь...


E>Если так, то в качестве примера, нарисуй нам горантирующий basic exception safety метод std::vector, который переаллоцирует буфер, и при этом поддерживает move-семантику соержимого...

E>Пусть у move-конструктора элемента тоже будет "basic exception safety", а у деструктора гарантия невылета...

А в чем, собственно, проблема? Если move конструктор не кидается (а с чего бы ему, по логике, кидаться?) то все элементарно. Если кидается, то тоже элементарно, но про move семантику придется забыть. Здесь, например.
www.blinnov.com
Re[24]: Вот еще, или я, кажется, читать разучился
От: jazzer Россия Skype: enerjazzer
Дата: 25.02.13 03:50
Оценка: 5 (1)
Здравствуйте, Erop, Вы писали:

E>Я верно же понимаю, что под "basic exception safety" понимают гарантию того, что при вылете исключения, могут быть сторонние эффекты, но не могут нарушаться инварианты и не случится утечек?..

Да.

E>Если так, то в качестве примера, нарисуй нам гарантирующий basic exception safety метод std::vector, который переаллоцирует буфер, и при этом поддерживает move-семантику соержимого...

E>Пусть у move-конструктора элемента тоже будет "basic exception safety", а у деструктора гарантия невылета...

Т.е. предполагается, что move-конструктор может бросить исключение? И нафига он такой нужен, если он фактически убивает оба объекта?

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

E>Для начала придумай, например, как тестированием гарантировать, что ты покрыл все варианты потоков исполнения кода?..

А зачем это надо гарантировать?

J>>И не надо. Код надо писать, имея в виду, что почти любая функция может бросить исключение. Т.е. тотальный RAII.


E>Это вообще никак не гарантирует "basic exception safety"...

J>>Не имею никакого геморроя с RAII-обертками, что я делаю не так?
E>Ты всё делаешь так.
E>Покажи нам мастер-класс, пожалуйста. На примере переаллокации буфера вектора, например
Для очистки-то вектора? Ты точно сам не сможешь?

J>>Опять же, утверждение про obfuscate противоречит моему опыту.

E>Теперь давай напишем структуру, поля которой -- A.
E>Для неё как будем сильную безопасность обеспечивать?..
Так же
E>А теперь небольшую базу данных (метров на триста, например), в памяти...
Мы вроде про obfuscate говорили, не? А не про расход памяти и т.п?
Но если ты хочешь оптимизировать, то придется забыть о концептуальной чистоте кода — оптимизированные решения почти всегда выглядят на порядок сложнее, чем наивный неоптимизированный код. Duff's device будет хорошим примером.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[22]: Вот еще, или я, кажется, читать разучился
От: Patalog Россия  
Дата: 25.02.13 05:16
Оценка: 1 (1) +1
Здравствуйте, alex_public, Вы писали:

[]

_>Да, и кстати как раз под этот конкретный пример... Не исключено что обработка ошибок через исключения в данном случае заняла бы больший объём кода, чем даже корректная (а не как в примере) обработка через возвращаемое значение. Потому как там такая логика, что при возникновение ошибок главная функция не прерывается, а просто не выполняет какую-то команду там дальше. Т.е. тут не работает главная фишка исключений с раскруткой стека и обработкой снаружи главной функции и надо ставить try catch чуть ли не вокруг каждого вызова внутренних функций. И это как раз то, о чём я писал в той темке когда-то, что в отличие от теории, применение исключений на практике часто неудобнее старых методов...


Таких сценариев "просто не выполняет какую-то команду там дальше" исчезающе мало. Из моего опыта подходит только разбор какого-то сложного формата данных из недоверенного источника, при чем не просто разбор (с целью скажем показать картинку), а с целью анализа именно ошибок входных данных.
Т.е. цель разбора\обработки является выдача результата проверки соответствия входных данных спецификации.
Прикол в том, что при таких сценариях работы "ошибки формата" перестают быть исключительными ситуациями, а становятся частью основной логики, т.е. об исключениях в терминах С++ речь уже не идет. =)
Почетный кавалер ордена Совка.
Re[25]: Вот еще, или я, кажется, читать разучился
От: Erop Россия  
Дата: 25.02.13 05:58
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Если кидается, то тоже элементарно, но про move семантику придется забыть.

Я просил таки с move-семантикой, коллега...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[16]: Вот еще, или я, кажется, читать разучился
От: zaufi Земля  
Дата: 25.02.13 06:11
Оценка: 28 (4) +3
Здравствуйте, niXman, Вы писали:

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


MTD>>1. Бородатые дядьки которые в начале 90-х попробовали С++ и обожглись, а теперь негативный опыт проецируют на сегодняшнее положение дел

X>а что, в начале 90-ых, с исключениями в с++ было не так?
X>(я тогда еще совсем сопливый был)

более менее плотно с исключениями я познакомился в начале 2000ных -- это было время жутких багов с поддержкой исключений в gcc/egcs %)
наш софт мы тестировали на снапшотах этих компиляторов: с одной стороны хотелось нормальной поддержки шаблонов, а с другой стороны время от времени они там вносили новые баги и легко могло получиться, что в новом снапшоте в критическом месте исключение просто не ловится catch блоком %)

через некоторое время egcs и gcc опять слились воедино, и поддержка исключений более менее стабилизировалась. но реализация была на SJLJ (дающая оверхед просто на входе в try блок), что в определенных случаях было критично и приходилось запариваться...

в gcc3 появилась обработка исключений основанная на таблицах... но в ранних версиях ессно безбожно глючная (поэтому мы собирали свой софт самосборной gcc3 с включенными sjlj при конфигурении -- они хоть как-то работали и были известны подводные камни). gcc3 мы оч любили за то, что в этом релизе девелоперы плотно поработали над кодогенерацией для AMD и наш софт на Athlon'ах XP работал на 20-30% быстрее чем на пнях тех лет.

только примерно с версии 3.4 (после многих тщательных тестов) мы стали бесстрашно использовать исключения по полной программе. примерно тогда же бенчмарки показали что запариваться с кодами возврата уже бессмысленно -- исключения куда удобнее и не несут уже жуткого оврхеда ни на подготовку (try) ни на обработку (catch)... особенно принимая во внимание вопрос читабельности и сопровождения кодовой базы в несколько миллионов строк. больше я тестов на скорость исключений не делал и поныне использую только исключения...
Re[25]: Вот еще, или я, кажется, читать разучился
От: Erop Россия  
Дата: 25.02.13 06:13
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Т.е. предполагается, что move-конструктор может бросить исключение? И нафига он такой нужен, если он фактически убивает оба объекта?


Почему нет?

J>В обоих случаях не будет утечек и все инварианты будут выполнены.

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

J>А зачем это надо гарантировать?

Некоторым этого хочется зачем-то...

E>>Покажи нам мастер-класс, пожалуйста. На примере переаллокации буфера вектора, например

J>Для очистки-то вектора? Ты точно сам не сможешь?
Ну тогда покажи то же но про два параллельных массива, например...

E>>Для неё как будем сильную безопасность обеспечивать?..

J>Так же
В смысле "так же"? Ты код давай.

J>Мы вроде про obfuscate говорили, не? А не про расход памяти и т.п?

Ну, если нам на производительность плевать, то на кой нам вообще С++? Шарп и вперёд и с песнями о том, что память больше не ресурс...

J>Но если ты хочешь оптимизировать, то придется забыть о концептуальной чистоте кода — оптимизированные решения почти всегда выглядят на порядок сложнее, чем наивный неоптимизированный код. Duff's device будет хорошим примером.


1) Duff's device на сегодня является писсимизацией.
2) Ничего клнцептуально сложного в нём, тем не менее нет, гарантии безопасности -- зна-а-а-ачительно сложнее концептуально
Последнее, но главное) Мы собственно уже моем считать, что я тебя убедил, что концепуально чистый прямой код на кодах возврата ЭФФЕКТИВНЕЕ такого же на исключениях?
И при этом ещё и использует более простые концепции?
{hr]Я не являюсь противником использования исключений. Но я являюсь противником концепции базовой гарантии безопасности. IMHO, она слишком оторванна от реальности и вообще нелогична.
Но это таки отдельный хитрый разговор.
То есть я думаю, что можно выработать такую гарантию, что она будет ПОМОГАТЬ, а не МЕШАТь писать концептуально чистый эффективный код. Но даже если ты её и выработаешь, то тебе будет трудно навязать её всему сообществу. С другой стороны, тебе негде будет иначе брать сотрудников, которые так умеют делать. То есть тебе прийдётся их вообще-то переучивать, что препятствует найму людей с большим опытом, кроме всего прочего.
Та же проблема, что с велосипедами, но только на уровне приёмов программирования, что ещё труднее формально навязать и проверить.
Так что я вполне понимаю конторы, которые говорят, что типа просто не надо вообще исключений и точка.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[23]: Вот еще, или я, кажется, читать разучился
От: Erop Россия  
Дата: 25.02.13 06:17
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Мое HO — данный конкретный пример как раз показывает, что такое исключительная ситуация. Плагин добавляет контролы. Если добавление какого-то контрола обламывается, то это именно исключительная ситуация без разговоров и самая правильная стратегия в данном случае — прекратить инициализацию вообще и не пытаться умничать.



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

Пример. ОТкрываешь ты НА ТЕЛЕФОНЕ прилажение для просмотра ТВ -- а у тебя подписка на ряд каналов закончилась. Думаешь не надо запускать?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[26]: Вот еще, или я, кажется, читать разучился
От: landerhigh Пират  
Дата: 25.02.13 06:19
Оценка: +1 :)
Здравствуйте, Erop, Вы писали:

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


L>>Если кидается, то тоже элементарно, но про move семантику придется забыть.

E>Я просил таки с move-семантикой, коллега...

Неправильный Вы форум выбрали для вопросов о скрещивании ежей с ужами, коллега
www.blinnov.com
Re[7]: Вот еще, или я, кажется, читать разучился
От: zaufi Земля  
Дата: 25.02.13 06:20
Оценка: :)
Здравствуйте, niXman, Вы писали:

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


L>>Да есть одна такая. На букву Г как раз.

X>понятно-понятно. не знал, что там тоже отказались от исключений. а говорят, что в Г работают только адекваты =)

вот недавно познакомился с внутренностями leveldb от этих адекватов. библа собирается без флага -fno-exceptions -- т.е. потенциально вылететь может да хотябы std::bad_alloc на многочисленных new, вставках в контейнеры или работе со строками... но адекваты ничего не ловят и даже (если вдруг захочется похакать их Makefile и вставить таки -fno-exceptions) нихера не проверяют что new что-то возвращает им валидное... RAII очевидно тоже забанен адекватами: ни каких smart указателй или lock_guardов! ВСЕ б***ь руками делается!
Re[23]: Вот еще, или я, кажется, читать разучился
От: Erop Россия  
Дата: 25.02.13 06:20
Оценка:
Здравствуйте, Patalog, Вы писали:

P>Таких сценариев "просто не выполняет какую-то команду там дальше" исчезающе мало.


Например, мы переоткрываем редакор или браузер и хотим восстановить открытые документы, как при закрытии...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[27]: Вот еще, или я, кажется, читать разучился
От: Erop Россия  
Дата: 25.02.13 06:24
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Неправильный Вы форум выбрали для вопросов о скрещивании ежей с ужами, коллега

Я верно понимаю, что ты не знаешь как это селать просто?..
Почему я не удивлён?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[8]: Вот еще, или я, кажется, читать разучился
От: niXman Ниоткуда https://github.com/niXman
Дата: 25.02.13 06:37
Оценка:
Здравствуйте, zaufi, Вы писали:

Z>... потенциально вылететь может да хотябы std::bad_alloc на многочисленных new, вставках в контейнеры или работе со строками... но адекваты ничего не ловят и даже (если вдруг захочется похакать их Makefile и вставить таки -fno-exceptions) нихера не проверяют что new что-то возвращает им валидное... RAII очевидно тоже забанен адекватами: ни каких smart указателй или lock_guardов! ВСЕ б***ь руками делается!


жуть какая
недавно я патчил V8, а конкретно — v8-shell. там я тоже заметил, что результат new не проверяется. но, подумал, что возможно конкретно этот участок кода написали лишь-бы-как. а получается что нет =)
в итоге, повставлял assert`ы.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[28]: Вот еще, или я, кажется, читать разучился
От: rusted Беларусь  
Дата: 25.02.13 06:43
Оценка: 1 (1)
Здравствуйте, Erop, Вы писали:

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


L>>Неправильный Вы форум выбрали для вопросов о скрещивании ежей с ужами, коллега

E>Я верно понимаю, что ты не знаешь как это селать просто?..
E>Почему я не удивлён?

А можно посмотреть пример объекта, у которого move-конструктор кидает исключения? Желательно с пояснением зачем там кидание и зачем вообще в таком случае пользоваться move-семантикой. Это не троллинга ради, я действительно с ходу не смог нафантазировать такого примера и теперь меня мучает любобытство.
Re[29]: Вот еще, или я, кажется, читать разучился
От: niXman Ниоткуда https://github.com/niXman
Дата: 25.02.13 06:45
Оценка:
Здравствуйте, rusted, Вы писали:

R>А можно посмотреть пример объекта, у которого move-конструктор кидает исключения? Желательно с пояснением зачем там кидание и зачем вообще в таком случае пользоваться move-семантикой. Это не троллинга ради, я действительно с ходу не смог нафантазировать такого примера и теперь меня мучает любобытство.


присоединяюсь к вопросу.
так же, не смог придумать ситуации, когда move-конструктору нужно кидать исключение.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[24]: Вот еще, или я, кажется, читать разучился
От: landerhigh Пират  
Дата: 25.02.13 06:46
Оценка: +1
Здравствуйте, Erop, Вы писали:

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


L>>Мое HO — данный конкретный пример как раз показывает, что такое исключительная ситуация. Плагин добавляет контролы. Если добавление какого-то контрола обламывается, то это именно исключительная ситуация без разговоров и самая правильная стратегия в данном случае — прекратить инициализацию вообще и не пытаться умничать.


E>Самая правильная -- иметь возможность управлять этим на уровне конфигуратора приложения.

E>Ну там критические плагины, например, не грузить нельзя, а просто свистелки с перделками -- какие проблемы?

Это один плагин. Читай внимательнее.

E>Проблема с кучей мессэдж боксов о незагрузки или неоткрытии чего-то -- вообще интерфейскная и к теме обработки исклюнией отношения не имеет...


Имеет. Это звенья одной цепи. Тут недодумали, там не заметили, тут понядеялись.

E>Пример. ОТкрываешь ты НА ТЕЛЕФОНЕ прилажение для просмотра ТВ -- а у тебя подписка на ряд каналов закончилась. Думаешь не надо запускать?..


В вышеприведенном случае скорее — включаешь телевизор, а кнопки "сделать потише" и "выключить" нет.

Хинт — "закончилась подписка" — это даже не ошибка, а ожидаемое событие. "У телевизора отвалилась ручка громкости" — это исключение класса "полярный лисец".
www.blinnov.com
Re[28]: Вот еще, или я, кажется, читать разучился
От: MTD https://github.com/mtrempoltsev
Дата: 25.02.13 07:23
Оценка:
Здравствуйте, Erop, Вы писали:

E>Я верно понимаю, что ты не знаешь как это селать просто?..


Пожалуйста, сначала разумную причину делать это.
Re[28]: Вот еще, или я, кажется, читать разучился
От: landerhigh Пират  
Дата: 25.02.13 07:24
Оценка:
Здравствуйте, Erop, Вы писали:

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


L>>Неправильный Вы форум выбрали для вопросов о скрещивании ежей с ужами, коллега

E>Я верно понимаю, что ты не знаешь как это селать просто?..

Нет. Я не понимаю, зачем это в принципе нужно пытаться сделать. Могу предложить ради разнообразия еще траву покосить в противогазе — занятие примерно одного рода по осмысленности.

E>Почему я не удивлён?


Откуда я знаю?
www.blinnov.com
Re[29]: Вот еще, или я, кажется, читать разучился
От: Erop Россия  
Дата: 25.02.13 08:38
Оценка:
Здравствуйте, rusted, Вы писали:

R>А можно посмотреть пример объекта, у которого move-конструктор кидает исключения? Желательно с пояснением зачем там кидание и зачем вообще в таком случае пользоваться move-семантикой. Это не троллинга ради, я действительно с ходу не смог нафантазировать такого примера и теперь меня мучает любобытство.


Ну, например, можно представить себе объект все действия с которым логгируются...
Или можно представить себе конструктор перемещения, который чем-то вроде assert'а кидающего logic_error, проверяет валидность перемещаемого объекта...

Но в целом это не важно.
Я же просил просто пример функции написать, раз это так просто всё якобы.

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

Мой поинт тоньше. Общепринятая система гарантий безопасности при исключениях вообще бессмысленна, так как её трудно воспроизводить на следующем уровне кода. То есть имея бибиотеку со строгой гарантией, легко писать код с базовой, а если мы хотим сохранить уровень гарантий, то приходится идти на оверхед, или усложнение кода, или и то и то, при этом усложнённый код ещё фиг протестируешь и отладишь, то есть мы имеем сложный и при этом редковызываемый, а потому труднотестируемый участок кода, что не есть гуд.
А оверхед, зато, легкотестируем и всегдавызываем, но это скорее недостаток, а не достоинство
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[29]: Кода мы так и не увидим, значит?..
От: Erop Россия  
Дата: 25.02.13 08:39
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Нет. Я не понимаю, зачем это в принципе нужно пытаться сделать. Могу предложить ради разнообразия еще траву покосить в противогазе — занятие примерно одного рода по осмысленности.


И как трава? Забористая?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[23]: Вот еще, или я, кажется, читать разучился
От: alex_public  
Дата: 25.02.13 08:57
Оценка: +1
Здравствуйте, landerhigh, Вы писали:

L>Мое HO — данный конкретный пример как раз показывает, что такое исключительная ситуация. Плагин добавляет контролы. Если добавление какого-то контрола обламывается, то это именно исключительная ситуация без разговоров и самая правильная стратегия в данном случае — прекратить инициализацию вообще и не пытаться умничать. Никогда не встречали программы, которые при каких-либо сценариях выдавали по полторы сотни мессаджбоксов друг за другом, каждый с многозначительным сообщением типа "ошибка инициализации"?


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

L>Здесь исключение — наиболее натуральный вариант. Выход по первому error, в принципе, тоже сработает, но получился лес if-ов.


Я в таких случаях инвертирую логику и получается просто много return, a не лесенка if-ов. Это я естественно про те случаи, где не использую исключения.

L>Кстати, из кода очевидно, что код этот никак не тестировался для негативного случая.


Да код вообще дикий. Но тем не менее никто тут так и не решился показать как бы он написал этот код через исключения. )))
Re[23]: Вот еще, или я, кажется, читать разучился
От: alex_public  
Дата: 25.02.13 09:04
Оценка:
Здравствуйте, Patalog, Вы писали:

P>Таких сценариев "просто не выполняет какую-то команду там дальше" исчезающе мало. Из моего опыта подходит только разбор какого-то сложного формата данных из недоверенного источника, при чем не просто разбор (с целью скажем показать картинку), а с целью анализа именно ошибок входных данных.

P>Т.е. цель разбора\обработки является выдача результата проверки соответствия входных данных спецификации.

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

P>Прикол в том, что при таких сценариях работы "ошибки формата" перестают быть исключительными ситуациями, а становятся частью основной логики, т.е. об исключениях в терминах С++ речь уже не идет. =)


Ага, и я о том же. Только у меня класс ошибок, которые "перестают быть исключительными ситуациями" явно намного шире. )))
Re[25]: Вот еще, или я, кажется, читать разучился
От: Erop Россия  
Дата: 25.02.13 09:12
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Это один плагин. Читай внимательнее.


Да хоть бы и пять. Вот прикинь, нажимаю я в ворде "проверить орфографию", в документе у меня русский и пара английских ID, ворд значит не смог загрузить английский спеллер и такой вообще орфографию не проверяет, или, вовсе отгружается по terminate.
Правда зачётное западло?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[16]: Вот еще, или я, кажется, читать разучился
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 25.02.13 09:23
Оценка: +1 :)
Здравствуйте, niXman, Вы писали:

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


MTD>>1. Бородатые дядьки которые в начале 90-х попробовали С++ и обожглись, а теперь негативный опыт проецируют на сегодняшнее положение дел

X>а что, в начале 90-ых, с исключениями в с++ было не так?
X>(я тогда еще совсем сопливый был)

В Borland C++ и BCB до 5 версии, с исключениями был полный ахтунг. BCB5, на серьезном проекте, тоже под занавес отупел (бинарник валился при обработке исключения).

Что касается вообще плюсов, то на мой субъектный взгляд, только после появления VS2005 стало не страшно писать "по-настоящему интересные программы"
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[17]: Вот еще, или я, кажется, читать разучился
От: Erop Россия  
Дата: 25.02.13 09:54
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Что касается вообще плюсов, то на мой субъектный взгляд, только после появления VS2005 стало не страшно писать "по-настоящему интересные программы"


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

IMHO, ещё не выработаны правильные подходы и оценки, и сами "тру-С++-фичи" тоже ещё будут меняться, пока не станут удобными и юзабельными без ограничений.

Хотя я исключения обычно использую, но не совсем так, как учат нас мэтры исключитеного-с-плюс-плюсения, но если есть какие-то причины этого не делать, то не использую без особых проблем, тоже...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[26]: Вот еще, или я, кажется, читать разучился
От: jazzer Россия Skype: enerjazzer
Дата: 25.02.13 10:33
Оценка: 4 (1)
Здравствуйте, Erop, Вы писали:

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


J>>Т.е. предполагается, что move-конструктор может бросить исключение? И нафига он такой нужен, если он фактически убивает оба объекта?

E>Почему нет?
Т.е. осмысленных причин нет?

J>>В обоих случаях не будет утечек и все инварианты будут выполнены.

E>Ну вот и приведи код, и мы потом его сравним с кодом, который без гарантий, насколько сложнее оно, проще и т. д...
Начнем с того, что у класса, который не обеспечивает базовой гарантии, даже деструктор нельзя звать — инварианты-то нарушены, а значит, деструктор может сделать все, что угодно, расстрелять любую память, позвать деструкторы дважды и т.п. В отсутствии базовой безопасности поведение программы при вылете исключения в общем случае неопределено, ее даже грохнуть корректно нельзя.
И ты говоришь: А давай код, который делает хз что и может отформатировать винчестер, сравним с кодом, который сделает все правильно, и посмотрим, что проще.
Типа а давай сварим суп из всех найденных грибов, и сравним его сложность с супом из только съедобных грибов.
Сравнивать, конечно, можно, но только смысла в этом ноль.

Но раз уж ты так просишь — вот (пишу прямо в браузере, не компилировал):
void reserve(size_t new_capacity)
{
  char* old_buf = buf_;
  buf_ = new char[new_capacity*sizeof(T)];
  capacity_ = new_capacity;
  const size_t orig_size = size_;
  // в конце в любом случае прибьем old_buf со всем содержимым
  on_scope_exit( [=]{ 
    for (size_t i=0; i<orig_size; ++i) ((T&)( old_buf[i*sizeof(T)] )).~T();
    delete[] old_buf;
  });
  // попробуем покопировать, нехай исключения летят
  for (size_=0; size_<orig_size; ++size_)
    new (&buf_[size_*sizeof(T)]) T(std::move( (T&)old_buf[size_*sizeof(T)] ));
}

Давай теперь то же на кодах возврата. Особенно сексуально будут выглядеть коды возврата из конструктора неизвестного типа и их смешение с ошибкой выделения памяти для буфера.

E>Ну тогда покажи то же но про два параллельных массива, например...

это еще что? У тебя развлечение такое — мне задания на кодинг выдумывать?

E>>>Для неё как будем сильную безопасность обеспечивать?..

J>>Так же
E>В смысле "так же"? Ты код давай.
Замени А на Б в коде.

J>>Мы вроде про obfuscate говорили, не? А не про расход памяти и т.п?

E>Ну, если нам на производительность плевать, то на кой нам вообще С++? Шарп и вперёд и с песнями о том, что память больше не ресурс...
Ты не подменяй тему обсуждения, а... Речь шла о том, что код становится запутанным — я показал, что не становится.
Если хочешь обсудить оптимизацию и как она влияет на понятность кода — я готов. Заодно расскажешь, как замечательно делается аналогичная оптимизация на кодах возврата.

J>>Но если ты хочешь оптимизировать, то придется забыть о концептуальной чистоте кода — оптимизированные решения почти всегда выглядят на порядок сложнее, чем наивный неоптимизированный код. Duff's device будет хорошим примером.


E>1) Duff's device на сегодня является писсимизацией.

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

E>2) Ничего клнцептуально сложного в нём, тем не менее нет, гарантии безопасности -- зна-а-а-ачительно сложнее концептуально

Да что ты говоришь. Убрать за собой в случае вылета исключения — это же так сложно.

E>Последнее, но главное) Мы собственно уже моем считать, что я тебя убедил, что концепуально чистый прямой код на кодах возврата ЭФФЕКТИВНЕЕ такого же на исключениях?

E>И при этом ещё и использует более простые концепции?
Самая простая концепция — вообще забить на любую обработку ошибок. Текст программы становится ну просто загляденье. И никаких гарантий — в точности то, что ты хочешь

E>{hr]Я не являюсь противником использования исключений. Но я являюсь противником концепции базовой гарантии безопасности. IMHO, она слишком оторвана от реальности и вообще нелогична.

Почему она вдруг оторвана от реальности и нелогична? Так трудно убрать за собой? С кодами возврата этого делать не нужно?
Базовая — это просто уборка за собой и приведение программы в минимально рабочее состояние.
Сильная — это транзакции, надеюсь, их ты не будешь оторванными от жизни называть, а то я тебя в http://rsdn.ru/forum/db/ отправлю.

E>Но это таки отдельный хитрый разговор.

Велкам.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[27]: Вот еще, или я, кажется, читать разучился
От: niXman Ниоткуда https://github.com/niXman
Дата: 25.02.13 12:06
Оценка:
как я понял, таки нет ни одного аргумента(для прикладного софта [1]) почему не нужно использовать исключения.
может быть, кто-то соизволит зарезюмировать сабж, и запечатлеть его в веках? (в блоге, или создать тему на форуме в режиме read-only)


[1]
для микроконтройлеров — размер бинаря увеличивается.
для компилятор с SJLJ — создается незначительный ран-тайм оверхед, который скорее является оправданием.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[22]: Вот еще, или я, кажется, читать разучился
От: Evgeny.Panasyuk Россия  
Дата: 25.02.13 12:36
Оценка:
Здравствуйте, Шарль Ожье де Бац де Кастельмор, Вы писали:

ioj>Вы ( не вы лично, а все сторонники исключений в этом треде) вообще читаете что в гугловском документе написано?


  • http://www.rsdn.ru/forum/cpp/5077183.1
    Автор: Ops
    Дата: 21.02.13

  • http://www.rsdn.ru/forum/cpp/5077328.1
    Автор: jazzer
    Дата: 21.02.13

  • http://www.rsdn.ru/forum/cpp/5078123.1
    Автор: Evgeny.Panasyuk
    Дата: 21.02.13

    Но решение было сделано на основе другого фактора:

    "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."

    Period.

  • Re[23]: Вот еще, или я, кажется, читать разучился
    От: Evgeny.Panasyuk Россия  
    Дата: 25.02.13 12:54
    Оценка: 1 (1)
    Здравствуйте, jazzer, Вы писали:

    ioj>>К тому же в С++ нет finally

    J>И очень хорошо, что нету. Оставим finally недоязыкам типа Java, у которых нет RAII.

    Добавлю, что в конце концов "недоязыки" осознали свою ущербность, и ввели костыли подражающие RAII:
  • Java: The try-with-resources Statement
  • C#: using Statement
    Вот только с транзитивностью беда:

    The compositional properties of RAII, however, differ significantly from scope bound resources in that it allows for full encapsulation of the resources behind an abstraction. With the dispose pattern for resource management, "being a resource" becomes a property that is transitive to composition. That is, any object that is composed using a resource that requires resource management effectively itself becomes a resource that requires resource management.

  • Re[28]: Вот еще, или я, кажется, читать разучился
    От: landerhigh Пират  
    Дата: 25.02.13 13:15
    Оценка:
    Здравствуйте, niXman, Вы писали:

    X>[1]

    X>для микроконтройлеров — размер бинаря увеличивается.

    Это может влиять, но, как правило, у них достаточно ROM/флеша для рамзещения таблиц.
    Что точно влияет — это то, что компилятор может не поддерживать исключений. Потому что их туда не позаботились добавить. Да и не нужны они там обычно, КМК — в исключительной ситуации там проще перезагрузиться
    www.blinnov.com
    Re[30]: Вот еще, или я, кажется, читать разучился
    От: landerhigh Пират  
    Дата: 25.02.13 13:30
    Оценка: +1
    Здравствуйте, Erop, Вы писали:

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


    R>>А можно посмотреть пример объекта, у которого move-конструктор кидает исключения? Желательно с пояснением зачем там кидание и зачем вообще в таком случае пользоваться move-семантикой. Это не троллинга ради, я действительно с ходу не смог нафантазировать такого примера и теперь меня мучает любобытство.


    E>Ну, например, можно представить себе объект все действия с которым логгируются...

    E>Или можно представить себе конструктор перемещения, который чем-то вроде assert'а кидающего logic_error, проверяет валидность перемещаемого объекта...

    А если съесть еще этих мягких французских грибов, то можно себе вообще такого напредставлять!
    Если объект уже существует — он по определению валиден. Не говоря уже о том, что проверять валидность объектов при перемещении — это несколько, какое бы подобрать слово, retarded.

    E>Но в целом это не важно.

    E>Я же просил просто пример функции написать, раз это так просто всё якобы.

    Любая тема по обусждению RAII всегда скатывается в идиотизм с деструктором, кидающим при невозможности закрыть файл.
    То, что ты хочешь — это словесный онанизм примерно того же плана.
    www.blinnov.com
    Re[30]: Кода мы так и не увидим, значит?..
    От: landerhigh Пират  
    Дата: 25.02.13 13:31
    Оценка:
    Здравствуйте, Erop, Вы писали:

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


    L>>Нет. Я не понимаю, зачем это в принципе нужно пытаться сделать. Могу предложить ради разнообразия еще траву покосить в противогазе — занятие примерно одного рода по осмысленности.


    E>И как трава? Забористая?


    Откуда я знаю, какая у тебя на этот раз трава?
    www.blinnov.com
    Re[26]: Вот еще, или я, кажется, читать разучился
    От: landerhigh Пират  
    Дата: 25.02.13 13:37
    Оценка:
    Здравствуйте, Erop, Вы писали:


    L>>Это один плагин. Читай внимательнее.


    E>Да хоть бы и пять. Вот прикинь, нажимаю я в ворде "проверить орфографию", в документе у меня русский и пара английских ID, ворд значит не смог загрузить английский спеллер и такой вообще орфографию не проверяет, или, вовсе отгружается по terminate.


    Сдуру можно и horseraddish сломать, чо. Только к теме отношения не имеет.

    E>Правда зачётное западло?


    Закономерное следствие засилия индустрии специалистами по взвешиванию гномиков боингами.
    www.blinnov.com
    Re[28]: Вот еще, или я, кажется, читать разучился
    От: landerhigh Пират  
    Дата: 25.02.13 13:45
    Оценка:
    Здравствуйте, Erop, Вы писали:

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


    L>>Неправильный Вы форум выбрали для вопросов о скрещивании ежей с ужами, коллега

    E>Я верно понимаю, что ты не знаешь как это селать просто?..

    Вообще-то я знаю могу доказать очевидное в три строчки, что в общем случае кидающего move-конструктора в вакууме это сделать невозможно. А вот ты, похоже, этого так и не понял сюда просто потроллить пришел. И я тоже ничуть не удивлен.
    www.blinnov.com
    Re[27]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 25.02.13 14:14
    Оценка: :)
    Здравствуйте, jazzer, Вы писали:

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


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

    J>
    J>void reserve(size_t new_capacity)
    J>{
    J>  char* old_buf = buf_;
    J>  buf_ = new char[new_capacity*sizeof(T)];
    J>  capacity_ = new_capacity;  // обычно в векторе хранят не счётчик, а указатель за конец буфера, но это тут тонкости
    J>  const size_t orig_size = size_;
    J>  // в конце в любом случае прибьем old_buf со всем содержимым
    J>  on_scope_exit( [=]{ 
    J>    for (size_t i=0; i<orig_size; ++i) ((T&)( old_buf[i*sizeof(T)] )).~T();
    J>    delete[] old_buf;
    J>  });
    J>  // попробуем покопировать, нехай исключения летят
    J>  for (size_=0; size_<orig_size; ++size_)
    J>    new (&buf_[size_*sizeof(T)]) T(std::move( (T&)old_buf[size_*sizeof(T)] ));
    J>}
    J>

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

    J>Давай теперь то же на кодах возврата. Особенно сексуально будут выглядеть коды возврата из конструктора неизвестного типа и их смешение с ошибкой выделения памяти для буфера.

    Там не будет std::vector'а, там надо как-то иначе.
    Например, у типа будет не конструктор перемещения, а перегруженная функция ERR_CODE move_array_item( T& dst, T& src ), которая вернёт, смогла или нет,..
    точный аналог втоего кода тогда будет выглядеть как-то так:
    ERR_CODE reserve( size_t new_capacity )
    {
        ERR_CODE res = EC_Ok;  // это мантра ;)
        if( new_capacity <= capacity_ ) { // Этого у тебя не было, но положим, что ты про это забыл потому что код очень простой и понятный ;)
            return res;
        }
    
        assert( new_capacity > 0 ); 
    
        // Создаём копию буфера, и передвигаем в неё данные
        char* extra_buf = new char[new_capacity*sizeof(T)] );
        if( extra_buf == 0 ) {
            return EC_MemoryError;
        }
        
        size_t cp_size = 0;
        while( cp_size < size() && IsOk( res ) ) {
            res = move_array_item( ((T*)extra_buf)[cp_size], ((T*)buf_)[cp_size] );
        }
        // тут мы ещё можем решить, что разрушать. Например, можно разрушать старый буффер только если полностью получилось скопировать новый
        if( IsOk( res ) ) {
            std::swap( extra_buf, buf_ );
            std::swap( size_, cp_size );
            capacity_ = new_capaciry;
        }
    
        while( cp_size  > 0 ) {
            ( --cp_size + (T*)extra_buf )->~T();  // Разрушаю всё-таки с конца...
        }  
        
        delete[] extra_buf;
        return res;
    }

    длиннее, но проще. + учтено чуть больше всяких мелочей и содно выбрать что в случае аварии делаем.
    Но это всё равно класс спректированный под исключения. Например, если мы вспомним, что ещё бывают всякие там insert и erase, которым надо сдвигать куски буфера, то у нас начнутся проблемы.
    Либо нам надо будет написать походие циулы несколько раз. А всё потому, что мы не можем позволить себе иметь кусок памяти, где просто память и объекты перемешаны как попало...

    Зато, если без исключений пишем, или пости без исключений, например, то можно функцию move_array_item сделать чуть прикольнее.
    Типа такой:
    template<typename T> ERR_CODE move_array_item( void* dst, T* src )
    { 
        try {
            ::new T( std::move( *src ) );
            src->~T();
        } catch( ... ) {
            return EC_CopyError; // или как-то ещё, как оно последовательно сделано в окружении без исключений -- отдельная песня.
        }
        return EC_Ok; 
    }


    тогда у нас может быть шаблон ещё и такой:
    template<typename T> ERR_CODE move_array_of_items( void* dst, T* src, size_t &count )
    {
        ERR_CODE res = EC_Ok;
        size_t to_copy = count;
        while( to_copy-- > 0 ) {
            if( IsOk( res = move_array_item( dst, src ) ) ) {
                dst = 1 + (T*)dst;
                ++src;
            } else {
                count -= to_copy + 1;
                break;
            }
        }
        return res;
    }
    ну и для простоты ещё и такой:
    template<typename T> void destroy_array_of_items( T* dst, size_t count ) 
    {
        while( count > 0 ) {
            ( dst + --count )->~T();
        }
    }




    Ну и с этой инфраструктурой мы легко можем теперь писать разные штуки вроде insert...
    Кстати, я так думал, что ты заведёшь внутри reserve ещё одну копию вектора, в котором зарезервируешь нужный буффер, потом перенесёшь элементы и обменяешь это всё.


    E>>Ну тогда покажи то же но про два параллельных массива, например...

    J>это еще что? У тебя развлечение такое — мне задания на кодинг выдумывать?
    Я пытаюсь тебе показать, что сохранять инварианты в случае исключения весьма небесплатно. И даже гарантировать отсутствие утечек не всегда просто.

    J>Ты не подменяй тему обсуждения, а... Речь шла о том, что код становится запутанным — я показал, что не становится.

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

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

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

    E>>2) Ничего клнцептуально сложного в нём, тем не менее нет, гарантии безопасности -- зна-а-а-ачительно сложнее концептуально

    J>Да что ты говоришь. Убрать за собой в случае вылета исключения — это же так сложно.
    Конечно сложно, так как
    1) Вылет может произойти где угодно
    2) "Где угодно" вернуться к инвариантам всех данных во всей программе может быть трудно, если вообще возможно.
    А в это время может случиться какая-нибудь клизьма. Ну там деструктор какой-нибудь нежданно куда-то слазит, или ещё чего...

    E>>Последнее, но главное) Мы собственно уже моем считать, что я тебя убедил, что концепуально чистый прямой код на кодах возврата ЭФФЕКТИВНЕЕ такого же на исключениях?

    E>>И при этом ещё и использует более простые концепции?
    J>Самая простая концепция — вообще забить на любую обработку ошибок. Текст программы становится ну просто загляденье. И никаких гарантий — в точности то, что ты хочешь
    Почему? Писать везде if( IsOk( res ) ) res = следующая_часть_обработки( параметры ); так уж сложно?
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[31]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 25.02.13 14:54
    Оценка: -1
    Здравствуйте, landerhigh, Вы писали:

    L>А если съесть еще этих мягких французских грибов, то можно себе вообще такого напредставлять!

    Бро! Трава в противогазе, теперь французские грибы. То, что ты не уважаешь синтертику -- это правильно. А вот то, что ты такой напряжный -- нет. Джа не оценит

    L>Если объект уже существует — он по определению валиден. Не говоря уже о том, что проверять валидность объектов при перемещении — это несколько, какое бы подобрать слово, retarded.


    Некоторые проверяют валидность при ВСЕХ операциях. Способствует надёжности кода, между прочим...

    L>Любая тема по обусждению RAII всегда скатывается в идиотизм с деструктором, кидающим при невозможности закрыть файл.

    Э-э-э, гиде тут RAII файл или деструктор?

    L>То, что ты хочешь — это словесный онанизм примерно того же плана.

    IMHO ты хочешь помыться...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[31]: Кода мы так и не увидим, значит?..
    От: Erop Россия  
    Дата: 25.02.13 14:56
    Оценка:
    Здравствуйте, landerhigh, Вы писали:

    L>>>Нет. Я не понимаю, зачем это в принципе нужно пытаться сделать. Могу предложить ради разнообразия еще траву покосить в противогазе — занятие примерно одного рода по осмысленности.


    E>>И как трава? Забористая?


    L>Откуда я знаю, какая у тебя на этот раз трава?

    Разве этоя предлагал её в противогазе косить?..
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[27]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 25.02.13 14:57
    Оценка:
    Здравствуйте, landerhigh, Вы писали:

    E>>Да хоть бы и пять. Вот прикинь, нажимаю я в ворде "проверить орфографию", в документе у меня русский и пара английских ID, ворд значит не смог загрузить английский спеллер и такой вообще орфографию не проверяет, или, вовсе отгружается по terminate.

    L>Сдуру можно и horseraddish сломать, чо. Только к теме отношения не имеет.

    А разве ты что-то другое предлагал?..
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[29]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 25.02.13 14:58
    Оценка:
    Здравствуйте, landerhigh, Вы писали:

    L>Вообще-то я знаю могу доказать очевидное в три строчки, что в общем случае кидающего move-конструктора в вакууме это сделать невозможно. А вот ты, похоже, этого так и не понял сюда просто потроллить пришел. И я тоже ничуть не удивлен.


    Забавно. Докажи, потому, что я знаю, как написать...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[27]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 25.02.13 15:22
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    E>>Я не являюсь противником использования исключений. Но я являюсь противником концепции базовой гарантии безопасности. IMHO, она слишком оторвана от реальности и вообще нелогична.

    J>Почему она вдруг оторвана от реальности и нелогична? Так трудно убрать за собой? С кодами возврата этого делать не нужно?
    J>Базовая — это просто уборка за собой и приведение программы в минимально рабочее состояние.
    J>Сильная — это транзакции, надеюсь, их ты не будешь оторванными от жизни называть, а то я тебя в http://rsdn.ru/forum/db/ отправлю.

    E>>Но это таки отдельный хитрый разговор.

    J>Велкам.

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

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

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

    Вводим такое понятие, как данные, которые находятся в состоянии, которое позволяет их корректно разрушить. Ну назовём это как-то удаляемость данных, например.

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

    1б) реальная ошибка. logic_error типа. Тут нам и утечки пофигу, на самом деле. Реальность такова, что раз уж у нас logic_error, то мы мало чему можем верить. Так что всё равно будем отгружать массово.
    Или там не сразу отгружать, а по какому-то доп. ещё событию. Не важно. Важно что за отсутсвие утечек имеет смысл бороться в этом сценарии только если это просто. Усложнять код ради отсутствия утечек нет смысла.

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

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

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

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

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

    И я сильно подозреваю, что верный путь лежит примерно в этой стороне, так как общепринятые гарантии безопасности на самом деле выбраны произвольно и обе две являются избыточными, если мы всё-таки подразумеваем, что исключение -- это то, чего у пользователя случаться не должно...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[27]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 25.02.13 15:51
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>Почему она вдруг оторвана от реальности и нелогична? Так трудно убрать за собой? С кодами возврата этого делать не нужно?

    Это просто эмоции, а не аргументация. Программирование -- деятельность прагматическая и целенаправленная. У всего должна быть цель. Какова цель "уборки за собой"? Так ли уж это надо/эффективно/актуально?
    Как усилия по обеспечению этой уборки поднимают доходы компании? На сколько, опять же?
    С третьей стороны, если судить по популярности С#, то "убирать за собой" таки трудно и редко оправданно, с точки зрения разработки ПО в рамках бизнеса

    J>Сильная — это транзакции, надеюсь, их ты не будешь оторванными от жизни называть, а то я тебя в http://rsdn.ru/forum/db/ отправлю.

    Ну это вообще особый случай. И я, если честно, ни за что не доверился бы СУБД, целостность которой гарантируется не архитектурными решениями на высоком достаточно уровне, а тем, что якобы все структуры данных в этой программе на всех уровнях обеспечивают строгую гарантию
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[23]: Вот еще, или я, кажется, читать разучился
    От: ioj Ниоткуда  
    Дата: 25.02.13 16:55
    Оценка: +1
    Здравствуйте, jazzer, Вы писали:

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


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


    ioj>>Вы ( не вы лично, а все сторонники исключений в этом треде) вообще читаете что в гугловском документе написано?


    ioj>>When you add a throw statement to an existing function, you must examine all of its transitive callers. Either they must make at least the basic exception safety guarantee, or they must never catch the exception and be happy with the program terminating as a result. For instance, if f() calls g() calls h(), and h throws an exception that f catches, g has to be careful or it may not clean up properly.


    J>Все правильно написано. Они говорят о коде, который не был рассчитан на то, что могут появиться исключения, а ты вдруг их вводишь в одной единственной функции — тогда да, тебе надо просмотреть все места, откуда она вызывается, и далее по цепочке. Они только забыли добавить, что программа, видимо, изначально написана на Си, а не на С++.


    нет, это не так, здесь говорится о любом коде, даже если он рассчитан на исключения they must make at least the basic exception safety guarantee

    J>Это противоречит моему опыту. Basic exception safety достигается элементарно.

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

    void object::foo()
    {
      this.fielda = create_a();
      this.fieldb = create_b();
      this.fieldc = create_c();
    }


    не обладая секцией finally или catch(...) где бы проверяется инвариант, сразу априори разносчик багов. Брошено исключение — получай объект в состоянии Х. Как тебе здесь поможет raii? Здесь помогут только костыли вроде бустового scope_exit.

    J>Это все не нужно. "control flow of programs", написанных на исключениях (т.е. обеспечивающих по крайней мере базовую безопасность), анализировать как раз проще всего — они выполняются до конца или пока не вылетит исключение, причем не важно откуда (кроме nothrow-функций, естественно — они никогда ничего не должны бросать).


    процедуры использующие goto анализировать проще всего, они выполняются до конца или пока не перейдут к какой-то метке. я надеюсь аналогия понятна. эксепшны конечно гораздо технологичней, но ломают control flow они не меньше чем goto, как при этом проще анализировать — я теряюсь в догадках.

    J>Причем и в том, и в другом случае нам не нужно совершать дополнительных телодвижений по очистке и прочему, так как RAIIза всем проследит автоматически.


    J>..поскипано...

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

    J>И очень хорошо, что нету. Оставим finally недоязыкам типа Java, у которых нет RAII.

    boost::scope_exit не от хорошей жизни писан

    ioj>>поэтому ту же basic exception safety обеспечивать весьма геморройно, даже если тотально всё заворачивать в raii обвёртки

    J>Не имею никакого геморроя с RAII-обертками, что я делаю не так?

    ioj>>и даже если бы finally таки было, всё равно you're forced to obfuscate code to isolate the commit:

    ioj>>Exception safety requires both RAII and different coding practices. Lots of supporting machinery is needed to make writing correct exception-safe code easy. Further, to avoid requiring readers to understand the entire call graph, exception-safe code must isolate logic that writes to persistent state into a "commit" phase. This will have both benefits and costs (perhaps where you're forced to obfuscate code to isolate the commit). Allowing exceptions would force us to always pay those costs even when they're not worth it.

    J>А тут мы плавно подменили basic exception safety на strong exception safety и сделали вид, что говорим об одном и том же — молодца!

    ты увидел слово commit и сразу решил что это strong exception safety, нет, это не так, "commit" phase есть и у базовой гарантии, т.к. здесь говорится о логике сохранения постоянного состояния, т.е. об инварианте объекта, смотри ещё раз мой код выше.

    J>"avoid requiring readers to understand the entire call graph" — нафиг никому не нужен the entire call graph. Потому что функция либо играет до конца, либо вылетает по ислючению. Всё.


    см. про goto, это усложняет понимание кода

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


    J>Где ты тут видишь obfuscate?

    тут нет, в реальном мире да.
    нормально делай — нормально будет
    Re[24]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 25.02.13 17:03
    Оценка:
    Здравствуйте, ioj, Вы писали:


    ioj>
    ioj>void object::foo()
    ioj>{
    ioj>  this.fielda = create_a();
    ioj>  this.fieldb = create_b();
    ioj>  this.fieldc = create_c();
    ioj>}
    ioj>



    Справедливости ради, надо сказать, что конкртено это можно написать и не так уж и криво...

    Но всё равно чисто локальными мерами надёжность нельзя обеспечить в принципе, так что весб подход с гарантиями глупый.
    То не говорит, на самом деле, о полной неюзабедбности исключений. Просто через строгую и бащовую гарантии их использовать не очень хорошо, но это не значит, что нет других тактик...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[28]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 25.02.13 20:03
    Оценка: -5
    Здравствуйте, niXman, Вы писали:

    X>как я понял, таки нет ни одного аргумента(для прикладного софта [1]) почему не нужно использовать исключения.

    X>может быть, кто-то соизволит зарезюмировать сабж, и запечатлеть его в веках? (в блоге, или создать тему на форуме в режиме read-only)

    X>[1]

    X>для микроконтройлеров — размер бинаря увеличивается.
    X>для компилятор с SJLJ — создается незначительный ран-тайм оверхед, который скорее является оправданием.

    Главным и пожалуй единственным аргументом для меня является бритва Оккама. Т.к. на практике переход на исключения в 95% случаев увеличивает сложность и объём кода. В оставшиеся же 5% у нас исключения вполне используются, так что отказ совсем не "религиозный" и абсолютный. Однако глядя на это соотношения, я вполне могу понять компании, которые запрещают исключения в принципе...
    Re[29]: Вот еще, или я, кажется, читать разучился
    От: niXman Ниоткуда https://github.com/niXman
    Дата: 25.02.13 20:09
    Оценка: +1
    Здравствуйте, alex_public, Вы писали:

    _>Главным и пожалуй единственным аргументом для меня является бритва Оккама. Т.к. на практике переход на исключения в 95% случаев увеличивает сложность и объём кода.

    на протяжении всего треда, я вижу лишь обратное. (в реальности-то, оно давно обосновано и доказано)
    не понимаю, откуда у вас такие выводы, после 14ти страниц писанины...
    пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
    Re[30]: Это-то как раз просто решается...
    От: Erop Россия  
    Дата: 25.02.13 20:23
    Оценка:
    Здравствуйте, niXman, Вы писали:

    X>на протяжении всего треда, я вижу лишь обратное. (в реальности-то, оно давно обосновано и доказано)

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

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

    Или ты уже и так с ними расстался настолько, что не рискнёшь предложить коллегам по 100 баксов за каждый уникальный случай нарушения гарантий?..
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[31]: Это-то как раз просто решается...
    От: Abyx Россия  
    Дата: 25.02.13 21:01
    Оценка: 56 (5) +2 :))
    Здравствуйте, Erop, Вы писали:

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


    X>>на протяжении всего треда, я вижу лишь обратное. (в реальности-то, оно давно обосновано и доказано)

    E>Смотри, ты пишешь же на С++ и с исключениями, и весь твой код обеспечивает как минимум базовую гарантию безопасности?

    E>Если ты так или иначе работаешь в команде, то предлагаю тебе эксперимент.

    E>Объявляешь приз в 100 баксов за каждый выявленный в твоём коде случай нарушения базовой гарантии и башляешь до тех пор, пока не расстанешься с иллюзиями

    E>Или ты уже и так с ними расстался настолько, что не рискнёшь предложить коллегам по 100 баксов за каждый уникальный случай нарушения гарантий?..


    а тебе надо организовать приз за каждый пропущенный код ошибки.
    In Zen We Trust
    Re[30]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 25.02.13 21:53
    Оценка: +2
    Здравствуйте, niXman, Вы писали:

    X>на протяжении всего треда, я вижу лишь обратное. (в реальности-то, оно давно обосновано и доказано)

    X>не понимаю, откуда у вас такие выводы, после 14ти страниц писанины...

    Эээ, покажите хоть одно одно доказательство в этой теме. Тут собственно на эту тему вообще был ровно один кусок кода (то, что обсуждал Егор — это немного другая тема уже) — пример кривой реализации обработки ошибок через коды. И всё. Ни одного другого примера не было. Ни примера правильной реализации через коды, ни примера реализации через исключения, что бы сравнить их красоту и объём... И где вы тут увидели хоть какие-то реальные аргументы? Одно бросание теоретическими лозунгами.
    Re[31]: Вот еще, или я, кажется, читать разучился
    От: landerhigh Пират  
    Дата: 25.02.13 22:17
    Оценка: +2
    Здравствуйте, alex_public, Вы писали:

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


    X>>на протяжении всего треда, я вижу лишь обратное. (в реальности-то, оно давно обосновано и доказано)

    X>>не понимаю, откуда у вас такие выводы, после 14ти страниц писанины...

    _>Эээ, покажите хоть одно одно доказательство в этой теме. Тут собственно на эту тему вообще был ровно один кусок кода (то, что обсуждал Егор — это немного другая тема уже) — пример кривой реализации обработки ошибок через коды. И всё. Ни одного другого примера не было. Ни примера правильной реализации через коды, ни примера реализации через исключения, что бы сравнить их красоту и объём... И где вы тут увидели хоть какие-то реальные аргументы? Одно бросание теоретическими лозунгами.


    Вообще-то вся темя — это обсуждение новомодного фреймвор.. нет, framewreck-а. Где из-за отказа от исключений внедрили передовые технологии "двухфазной инициализации" и революционный подход "объект после вызова конструктора может оказаться в черт-те каком состоянии". Правда, как оказалось, конструктор копирования инновациями не удостоили, поэтому ждем следующей версии.

    Почти вся последовавшая дискуссия — это натягивание совы на глобус с попытками придумать, где обработка исключительных ситуаций через коды возврата будет удобнее или оправданне исключений.
    www.blinnov.com
    Re[28]: Вот еще, или я, кажется, читать разучился
    От: landerhigh Пират  
    Дата: 25.02.13 22:20
    Оценка:
    Здравствуйте, Erop, Вы писали:

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


    E>>>Да хоть бы и пять. Вот прикинь, нажимаю я в ворде "проверить орфографию", в документе у меня русский и пара английских ID, ворд значит не смог загрузить английский спеллер и такой вообще орфографию не проверяет, или, вовсе отгружается по terminate.

    L>>Сдуру можно и horseraddish сломать, чо. Только к теме отношения не имеет.

    E>А разве ты что-то другое предлагал?..


    Значит, я угадал. И почему я не удивлен?

    Тебе еще читать следовало бы научиться, но, кажется, уже поздновато.
    www.blinnov.com
    Re[24]: Вот еще, или я, кажется, читать разучился
    От: landerhigh Пират  
    Дата: 25.02.13 22:27
    Оценка: +1
    Здравствуйте, ioj, Вы писали:


    ioj>и это _не_ элементарно, это ровным счётом настолько же элементарно как и везде натыкать проверку возвращаемых значений, т.к. при возможности выброса исключения из любого метода, код вроде этого ( а фактически это любой метод, т.к. в почти во всех не константных методах есть участок где нарушен инвариант класса ):


    ioj>
    ioj>void object::foo()
    ioj>{
    ioj>  this.fielda = create_a();
    ioj>  this.fieldb = create_b();
    ioj>  this.fieldc = create_c();
    ioj>}
    ioj>


    Что это за метод такой, который не принимает параметров и ничего не возвращает? Это private, который вызывается только из конструктора? Тогда никаких проблем, пусть себе кидает.
    Если нет, то это — говнокод без вариантов, по сути версия метода Construct обсуждаемого фреймворка. Period.
    www.blinnov.com
    Re[32]: Кода мы так и не увидим, значит?..
    От: landerhigh Пират  
    Дата: 25.02.13 23:12
    Оценка: :)
    Здравствуйте, Erop, Вы писали:

    L>>Откуда я знаю, какая у тебя на этот раз трава?

    E>Разве этоя предлагал её в противогазе косить?..

    Ну ты же так и ниасилил обосновать, зачем тебе нужен подобный фестиваль. Все, что мы услышали — это то, что ты "знаешь, как". Ну, знай дальше.
    www.blinnov.com
    Re[32]: Вот еще, или я, кажется, читать разучился
    От: landerhigh Пират  
    Дата: 25.02.13 23:14
    Оценка: 1 (1) +1
    Здравствуйте, Erop, Вы писали:


    L>>Если объект уже существует — он по определению валиден. Не говоря уже о том, что проверять валидность объектов при перемещении — это несколько, какое бы подобрать слово, retarded.

    E>Некоторые проверяют валидность при ВСЕХ операциях. Способствует надёжности кода, между прочим...

    А валидность проверки валидности ты тоже проверяшеь? Нет? О какой надоежности тогда можно говорить?
    Впрочем, если у тебя даже при проверки валидности при всех операциях в контейнере оказываются невалидные объекты, то я умываю руки. Случай клинический.
    www.blinnov.com
    Re[30]: Вот еще, или я, кажется, читать разучился
    От: landerhigh Пират  
    Дата: 25.02.13 23:15
    Оценка:
    Здравствуйте, Erop, Вы писали:

    L>>Вообще-то я знаю могу доказать очевидное в три строчки, что в общем случае кидающего move-конструктора в вакууме это сделать невозможно. А вот ты, похоже, этого так и не понял сюда просто потроллить пришел. И я тоже ничуть не удивлен.


    E>Забавно. Докажи, потому, что я знаю, как написать...


    Ты сначала потрудись обосновать, зачем это надо, знаток ты наш. Утром деньги — вечером стулья.
    www.blinnov.com
    Re[31]: Это-то как раз просто решается...
    От: niXman Ниоткуда https://github.com/niXman
    Дата: 26.02.13 05:19
    Оценка:
    Здравствуйте, Erop, Вы писали:

    E>Смотри, ты пишешь же на С++ и с исключениями, и весь твой код обеспечивает как минимум базовую гарантию безопасности?


    E>Если ты так или иначе работаешь в команде, то предлагаю тебе эксперимент.

    E>Объявляешь приз в 100 баксов за каждый выявленный в твоём коде случай нарушения базовой гарантии и башляешь до тех пор, пока не расстанешься с иллюзиями

    E>Или ты уже и так с ними расстался настолько, что не рискнёшь предложить коллегам по 100 баксов за каждый уникальный случай нарушения гарантий?..

    вы мусолите коня в вакууме. сами придумываете несуществующие проблемы, и сами их решаете. КПД 0%.
    успехов.
    пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
    Re[31]: Вот еще, или я, кажется, читать разучился
    От: niXman Ниоткуда https://github.com/niXman
    Дата: 26.02.13 05:23
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    _>Эээ, покажите хоть одно одно доказательство в этой теме. Тут собственно на эту тему вообще был ровно один кусок кода (то, что обсуждал Егор — это немного другая тема уже) — пример кривой реализации обработки ошибок через коды. И всё. Ни одного другого примера не было. Ни примера правильной реализации через коды, ни примера реализации через исключения, что бы сравнить их красоту и объём... И где вы тут увидели хоть какие-то реальные аргументы? Одно бросание теоретическими лозунгами.


    доказательств в теме полно. начиная от несуществующих проблем, и заканчивая тотальным словоблудием о несуществующих проблемах.
    повторюсь: КПД 0%
    пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
    Re[32]: Это-то как раз просто решается...
    От: niXman Ниоткуда https://github.com/niXman
    Дата: 26.02.13 05:31
    Оценка: +1
    Здравствуйте, niXman, Вы писали:

    X>сами придумываете несуществующие проблемы, и сами их решаете. КПД 0%.


    ах да, главное забыл..
    решение несуществующих проблем мне мало интересно. но обработка С++ ошибок в Си-стиле, всегда более запутанная и "дырявая". и это факт.
    пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
    Re[33]: Кода мы так и не увидим, значит?..
    От: Erop Россия  
    Дата: 26.02.13 06:12
    Оценка:
    Здравствуйте, landerhigh, Вы писали:

    L>Ну ты же так и ниасилил обосновать, зачем тебе нужен подобный фестиваль. Все, что мы услышали — это то, что ты "знаешь, как". Ну, знай дальше.


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

    Я утверждаю, что код с гарантиями будет сложнее и неэффективнее кода без гарантий. Только и всего.
    Но если тебе не интересно это обсуждение, то я не очень понимаю, что ты тут пишешьи зачем? Сожержание той пары книжек, из которых ты узнал про обработку исключений и про строгую и базовую гарантии ты пересказываешь не особо точно, примерно на уровне статьи из вики. Наверное для каких-то целей этого достаточно. Дальнейшее твоё участи в обсуждении какой смысл должно по твоему нести-то?
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[33]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 26.02.13 06:16
    Оценка: +1 -2
    Здравствуйте, landerhigh, Вы писали:

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


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

    Но в целом ты же умыл руки? И правильно сделал, по существу-то ты так ничего и не сказал, между прочим
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[31]: Интересно, как ты понимаешь фразу "могу доказать"?..
    От: Erop Россия  
    Дата: 26.02.13 06:18
    Оценка:
    Здравствуйте, landerhigh, Вы писали:

    L>>>Вообще-то я могу доказать очевидное в три строчки, что в общем случае кидающего move-конструктора в вакууме это сделать невозможно.

    E>>Забавно. Докажи, потому, что я знаю, как написать...

    L>Ты сначала потрудись обосновать, зачем это надо, знаток ты наш. Утром деньги — вечером стулья.


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

    Можешь привести доказательство, или это было так, фигурально выражаясь, так сказать?..
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[24]: Вот еще, или я, кажется, читать разучился
    От: Patalog Россия  
    Дата: 26.02.13 06:24
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    []

    _>А я как раз наоборот очень редко встречаю ситуации, когда требуется именно "конец работы в случае ошибки" (а только в таких случаях исключения действительно эффективны и собственно для этого они и создавались).


    Это не плохое, не годное понимание концепции "для этого они и создавались".

    P>>Прикол в том, что при таких сценариях работы "ошибки формата" перестают быть исключительными ситуациями, а становятся частью основной логики, т.е. об исключениях в терминах С++ речь уже не идет. =)


    _>Ага, и я о том же. Только у меня класс ошибок, которые "перестают быть исключительными ситуациями" явно намного шире. )))


    Вполне возможно.
    Мой поинт в том, что тот уровень обработки ошибок, который обеспечивает "сферический программист в вакууме" за которого так болеет тролльErop, с помощью исключений обеспечивается проще и приятнее.
    Ясное дело, когда начинаются holy wars, все внезапно пишут код не иначе как для "ядерных реакторов" (tm), и начинают сыпать терминами про вилидность\верифицируемость\гарантии etc.
    Почетный кавалер ордена Совка.
    Re[32]: Это-то как раз просто решается...
    От: Erop Россия  
    Дата: 26.02.13 06:29
    Оценка:
    Здравствуйте, niXman, Вы писали:

    E>>Или ты уже и так с ними расстался настолько, что не рискнёшь предложить коллегам по 100 баксов за каждый уникальный случай нарушения гарантий?..

    X>вы мусолите коня в вакууме. сами придумываете несуществующие проблемы, и сами их решаете. КПД 0%.
    Интересно, из чего ты сделал такой вывод?..
    Если ты не понял, то я утверждаю, что пока что ещё не видел большого проекта, в котором пытались обеспечить базовую гарантию, но при этом смогли это сделать на самом деле...

    То есть я НЕСКОЛЬКО раз проверял то, что гарантия якобы обеспечена, и КАЖДЫЙ раз выяснялось, что она очень во многих местах не обеспечена на самом деле...
    Просто я несколько раз переносил довольно большие проекты между платформами/компиляторами/ендианами/битностями и т. д. При таком переносе гамно из кода лезет только в путь. И я больше не верю заверениям типа того, "ну тут у нас везде жеж базовая гарантия"...

    Ты, насколько я тебя понял, думаешь, что веришь в то, что обеспечение базовой гарантии достижимо.
    Вот я и предлагаю тебе простой эксперемент, возможно мысленный, что бы проверить кропость и обоснованность твоей веры.
    Насколько я тебя понял, ты не готов предлагать по 100 баксов за обнаружения нарушения гарантий? Видимо это обозначает, что вера твоя не так уж и крепка
    А какую суммы то готов предложить, кстати? Ну хотя бы 10 баксов-то готов? Правда я сомневаюсь, что за 10 баксов много елающих будет что бы искать...

    X>успехов.

    Спасибо...

    Взаимно.
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[31]: Вот еще, или я, кажется, читать разучился
    От: MTD https://github.com/mtrempoltsev
    Дата: 26.02.13 06:38
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    _>Ни примера правильной реализации через коды


    Код покажи, чтобы начать разговор. Хорошо?
    Re[25]: Вот еще, или я, кажется, читать разучился
    От: ioj Ниоткуда  
    Дата: 26.02.13 06:41
    Оценка: -1 :)
    Здравствуйте, landerhigh, Вы писали:


    L>Что это за метод такой, который не принимает параметров и ничего не возвращает? Это private, который вызывается только из конструктора? Тогда никаких проблем, пусть себе кидает.

    L>Если нет, то это — говнокод без вариантов, по сути версия метода Construct обсуждаемого фреймворка. Period.

    это псевдокод, удивись ещё точке после this, умник, может ты суть будешь читать? можешь не отвечать, с тобой диалог тоже закончен.
    нормально делай — нормально будет
    Re[33]: Это-то как раз просто решается...
    От: niXman Ниоткуда https://github.com/niXman
    Дата: 26.02.13 07:00
    Оценка: :))
    Здравствуйте, Erop, Вы писали:

    E>То есть я НЕСКОЛЬКО раз проверял то, что гарантия якобы обеспечена, и КАЖДЫЙ раз выяснялось, что она очень во многих местах не обеспечена на самом деле...

    E>Просто я несколько раз переносил довольно большие проекты между платформами/компиляторами/ендианами/битностями и т. д. При таком переносе гамно из кода лезет только в путь. И я больше не верю заверениям типа того, "ну тут у нас везде жеж базовая гарантия"...

    возможно, причину нужно искать в себе, а не в инструментах/средствах/проектах/кодах?
    нет, я понимаю, что проще найти "виновника" вне себя. но вы должны понимать, что это временное "решение", и ухождение от решения истинной проблемы, только усугубляет ситуацию, и, как следствие, "затуманит" понимание истока проблемы.
    пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
    Re[32]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 07:12
    Оценка: :)
    Здравствуйте, landerhigh, Вы писали:

    L>Вообще-то вся темя — это обсуждение новомодного фреймвор.. нет, framewreck-а. Где из-за отказа от исключений внедрили передовые технологии "двухфазной инициализации" и революционный подход "объект после вызова конструктора может оказаться в черт-те каком состоянии". Правда, как оказалось, конструктор копирования инновациями не удостоили, поэтому ждем следующей версии.


    Да, я согласен что у них довольно сомнительное решение. Но хочу заметить что лично у меня такого вообще никогда не встречается. Видимо потому, что я считаю что что конструкторы объектов в любом случае не должны завершаться неудачей (т.е. ни исключений, ни двухфазных странностей). С поправкой на особый случай ситуации неудачи выделения оперативной памяти.
    Re[32]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 07:34
    Оценка: -1
    Здравствуйте, MTD, Вы писали:

    MTD>Код покажи, чтобы начать разговор. Хорошо?


    Вот, первый человек по делу что-то сказал. Хотя там в принципе был кусок кода, который обсуждали и можно было с ним поработать... Но он слишком громоздкий и кривой, поэтому для начала возьмём что-то совсем простое, типа такого:
    void OnInit()
    {
        ...
        string name=GetName();
        if(!ReadProfile(name)) CreateNewProfile(name);
        ...
    }


    Думаю логика работы очевидна, да? Так вот как будет выглядеть подобный код, если переписать его через исключения (их тогда бросает функция ReadProfile)? Он будет удобнее приведённого выше или нет?
    Re[32]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 07:37
    Оценка: +1 -1
    Здравствуйте, niXman, Вы писали:

    X>доказательств в теме полно. начиная от несуществующих проблем, и заканчивая тотальным словоблудием о несуществующих проблемах.

    X>повторюсь: КПД 0%

    Если уж сливаться из дискуссии, то хотя бы по нормальному, а не с таким пафосом...
    Re[33]: Вот еще, или я, кажется, читать разучился
    От: niXman Ниоткуда https://github.com/niXman
    Дата: 26.02.13 07:39
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    _>как будет выглядеть подобный код, если переписать его через исключения (их тогда бросает функция ReadProfile)? Он будет удобнее приведённого выше или нет?

    тут нет исключительной ситуации. думаю, ответ очевиден.

    зы
    ппц, когда люди начнут понимать, от какого слова появилось слово исключения в ЯП %)
    пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
    Re[33]: Вот еще, или я, кажется, читать разучился
    От: MTD https://github.com/mtrempoltsev
    Дата: 26.02.13 07:39
    Оценка: 7 (1) +3
    Здравствуйте, alex_public, Вы писали:

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

    _>
    _>void OnInit()
    _>{
    _>    ...
    _>    string name=GetName();
    _>    if(!ReadProfile(name)) CreateNewProfile(name);
    _>    ...
    _>}
    _>


    _>Думаю логика работы очевидна, да? Так вот как будет выглядеть подобный код, если переписать его через исключения (их тогда бросает функция ReadProfile)? Он будет удобнее приведённого выше или нет?


    Очевидна, но:
    1. Отсутствие профиля не является исключительной ситуацией
    2. А вот функция создания профиля вполне может столкнуться с исключительной ситуацией и ты эту ситуацию не обрабатываешь.
    Re[25]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 07:45
    Оценка: +2
    Здравствуйте, Patalog, Вы писали:

    P>Мой поинт в том, что тот уровень обработки ошибок, который обеспечивает "сферический программист в вакууме" за которого так болеет тролльErop, с помощью исключений обеспечивается проще и приятнее.


    Не согласен. На мой взгляд исключение действительно удобны только для очень узкого вида ошибок, которые должны приводить к глубокой раскрутке стека. Для большинства же случаев (а чаще всего какая-то минимальная обработка ошибок идёт уже на предыдущем уровне стека вызовов) на практике исключения привносят только увеличение сложности и объёма кода.
    Re[33]: Вот еще, или я, кажется, читать разучился
    От: niXman Ниоткуда https://github.com/niXman
    Дата: 26.02.13 07:45
    Оценка: +1
    Здравствуйте, alex_public, Вы писали:

    _>Если уж сливаться из дискуссии, то хотя бы по нормальному, а не с таким пафосом...

    если уж и пытаться выдавать себя за человека знающего сабж, то как минимум следовало прочитать хотя бы вводной курс про исключения, дабы не производить "то", что ты выдал выше.
    пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
    Re[26]: Вот еще, или я, кажется, читать разучился
    От: niXman Ниоткуда https://github.com/niXman
    Дата: 26.02.13 07:47
    Оценка: +2
    Здравствуйте, alex_public, Вы писали:

    _>на практике исключения привносят только увеличение сложности и объёма кода.

    конечно, если их использовать в качестве кодов возврата
    пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
    Re[33]: Вот еще, или я, кажется, читать разучился
    От: Patalog Россия  
    Дата: 26.02.13 07:48
    Оценка: 2 (1) +2
    Здравствуйте, alex_public, Вы писали:

    []

    _>Думаю логика работы очевидна, да? Так вот как будет выглядеть подобный код, если переписать его через исключения (их тогда бросает функция ReadProfile)? Он будет удобнее приведённого выше или нет?


    Имхо, приведенный код в данном контексте просто квинэссенция не понимания "для этого их и придумали".
    1. Зачем его переписывать через исключения, что було?
    Если ты можешь обработать "ошибку" на этом уровне, ее и нужно там обработать. Для данного случая это не ошибка, это нормальная ситуация.
    Исключением это будет если ты на этом уровне не можешь вызвать CreateNewProfile, тогда логично кинуть исключение,
    которое поймает тот уровень который может сделать CreateNewProfile.
    2. Или ты хочешь поговорить о том, нужно ли ф-и ReadProfile кидуть исключение вместо кода возврата?
    Почетный кавалер ордена Совка.
    Re[34]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 07:53
    Оценка: -1
    Здравствуйте, MTD, Вы писали:

    MTD>Очевидна, но:

    MTD>1. Отсутствие профиля не является исключительной ситуацией
    MTD>2. А вот функция создания профиля вполне может столкнуться с исключительной ситуацией и ты эту ситуацию не обрабатываешь.

    Т.е. ошибки работы с файловой системой мы обрабатываем без исключений, так? Отлично! У меня такое же мнение. А то мне в этой теме заявляли что вполне нормально ВСЕ ошибки обрабатывать через исключения и это будет всё равно лучше кодов возврата. Похоже что наши позиции не так уж сильно и отличаются... Теперь осталось только определиться, что же тогда на практике нам удобно обрабатывать через исключения? Ошибки выделения памяти видимо. А ещё что? )
    Re[34]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 07:57
    Оценка:
    Здравствуйте, Patalog, Вы писали:

    P>Имхо, приведенный код в данном контексте просто квинэссенция не понимания "для этого их и придумали".


    Ну так я о том и говорю)

    P>2. Или ты хочешь поговорить о том, нужно ли ф-и ReadProfile кидуть исключение вместо кода возврата?


    Естественно и вообще то это прямо и написано в том моём сообщение.
    Re[35]: Вот еще, или я, кажется, читать разучился
    От: niXman Ниоткуда https://github.com/niXman
    Дата: 26.02.13 07:59
    Оценка: +2
    Здравствуйте, alex_public, Вы писали:

    _>Т.е. ошибки работы с файловой системой мы обрабатываем без исключений, так? Отлично!

    я единственный не понимаю, из чего последовал этот вывод?
    пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
    Re[35]: Вот еще, или я, кажется, читать разучился
    От: Tanker  
    Дата: 26.02.13 08:00
    Оценка: +1
    Здравствуйте, alex_public, Вы писали:

    MTD>>1. Отсутствие профиля не является исключительной ситуацией

    MTD>>2. А вот функция создания профиля вполне может столкнуться с исключительной ситуацией и ты эту ситуацию не обрабатываешь.

    _>Т.е. ошибки работы с файловой системой мы обрабатываем без исключений, так? Отлично! У меня такое же мнение. А то мне в этой теме заявляли что вполне нормально ВСЕ ошибки обрабатывать через исключения и это будет всё равно лучше кодов возврата. Похоже что наши позиции не так уж сильно и отличаются... Теперь осталось только определиться, что же тогда на практике нам удобно обрабатывать через исключения? Ошибки выделения памяти видимо. А ещё что? )


    Все ошибки, кроме тех, где требуется максимально возможный перформанс и при это всегда есть возможность обработать ошибку непосредственно в вызывающем методе.
    Исключения нужны для того, что бы код обработки ошибок был в одном месте, а не везде по коду. Скажем это может быть публичный метод компонента. Глубина вызовов из этого метода может быть сколь угодно большой, это не создает никаких проблем для исключений.
    The animals went in two by two, hurrah, hurrah...
    Re[36]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 08:04
    Оценка:
    Здравствуйте, Tanker, Вы писали:

    _>>Т.е. ошибки работы с файловой системой мы обрабатываем без исключений, так? Отлично! У меня такое же мнение. А то мне в этой теме заявляли что вполне нормально ВСЕ ошибки обрабатывать через исключения и это будет всё равно лучше кодов возврата. Похоже что наши позиции не так уж сильно и отличаются... Теперь осталось только определиться, что же тогда на практике нам удобно обрабатывать через исключения? Ошибки выделения памяти видимо. А ещё что? )


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

    T>Исключения нужны для того, что бы код обработки ошибок был в одном месте, а не везде по коду. Скажем это может быть публичный метод компонента. Глубина вызовов из этого метода может быть сколь угодно большой, это не создает никаких проблем для исключений.

    Т.е. я правильно понимаю, что вот этот http://www.rsdn.ru/forum/cpp/5082668
    Автор: MTD
    Дата: 26.02.13
    пример вы бы переписали через исключения? Т.к. никакой перформанс там совсем не требуется...
    Re[37]: Вот еще, или я, кажется, читать разучился
    От: Tanker  
    Дата: 26.02.13 08:14
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    _>Т.е. я правильно понимаю, что вот этот http://www.rsdn.ru/forum/cpp/5082668
    Автор: MTD
    Дата: 26.02.13
    пример вы бы переписали через исключения? Т.к. никакой перформанс там совсем не требуется...


    Пока что не было никаких указаний, что это за код, на сервере, на клиенте, какие требования по перформансу и тд. Покажи все ограничения, тогда модно будет подумать. Если исключение создает проблему с перформансом, то этот код должен вызваться наверное миллион раз в секунду или чаще.
    The animals went in two by two, hurrah, hurrah...
    Re[38]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 08:19
    Оценка:
    Здравствуйте, Tanker, Вы писали:

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


    Я же говорю, никаких ограничений в этом смысле...

    Т.е. как я понял стали бы использовать, да?

    А какие преимущества (по сравнению с приведённым кодом) в данном конкретном случае вы от этого видите?
    Re[39]: Вот еще, или я, кажется, читать разучился
    От: Tanker  
    Дата: 26.02.13 08:22
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    _>Я же говорю, никаких ограничений в этом смысле...

    _>Т.е. как я понял стали бы использовать, да?

    Разумеется.

    _>А какие преимущества (по сравнению с приведённым кодом) в данном конкретном случае вы от этого видите?


    Что бы обработать CreateProfile нужно знать, как именно обрабатывать и иметь для этого все необходимые депенденсы. Соответсвенно без исключений такие вызовы надо обкладывать проверкой кода возврата и вызывать функцию обработчик ошибок.
    А с исключениями этого ничего не надо, достаточно в одном единственном месте указать try-catch и в нем обработать.
    The animals went in two by two, hurrah, hurrah...
    Re[35]: Вот еще, или я, кажется, читать разучился
    От: Patalog Россия  
    Дата: 26.02.13 08:33
    Оценка: +1
    Здравствуйте, alex_public, Вы писали:

    []

    P>>2. Или ты хочешь поговорить о том, нужно ли ф-и ReadProfile кидуть исключение вместо кода возврата?


    _>Естественно и вообще то это прямо и написано в том моём сообщение.


    Если ограничиваться только данным куском и вводными то OnInit'y ничего другого кроме как
    try
    { ReadProfile(name); }
    catch (profile_error const&)
    { CreateNewProfile(name); }

    не остается.
    Если посмотреть на задачу немножко более подробно — все может сложиться иначе (с)
    Почетный кавалер ордена Совка.
    Re[35]: Вот еще, или я, кажется, читать разучился
    От: MTD https://github.com/mtrempoltsev
    Дата: 26.02.13 08:38
    Оценка: 21 (1) +4
    Здравствуйте, alex_public, Вы писали:

    _>Теперь осталось только определиться, что же тогда на практике нам удобно обрабатывать через исключения?


    Очевидно это те ошибки которые нельзя обработать на данном уровне и игнорирование которых делает дальнейшую работу программы бессмысленной.
    Re[40]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 08:48
    Оценка:
    Здравствуйте, Tanker, Вы писали:

    _>>Т.е. как я понял стали бы использовать, да?

    T>Разумеется.

    Ну вот. А на меня тут уже несколько человек накинулось, зачем это я привёл этот пример. Вот как раз потому и привёл, что многие придерживаются вашей точки зрения. С которой лично я не согласен. Хотя это в какой-то степени дело вкуса конечно же.

    Кстати, а как вам точка зрения этих нескольких человек выше по темке, что мол этот случай не имеет никакого отношения к исключениям и соответственно его надо обрабатывать через коды возврата?

    P.S. Вот как раз существование вашей точки зрения и является для меня в какой-то степени обоснованием правильности бана некоторыми компаниями исключений вообще. Только без обид)
    Re[34]: Это-то как раз просто решается...
    От: Erop Россия  
    Дата: 26.02.13 08:49
    Оценка: +1
    Здравствуйте, niXman, Вы писали:

    X>возможно, причину нужно искать в себе, а не в инструментах/средствах/проектах/кодах?

    Ну ищи...

    Я тебе ещё раз говорю, что несколько лет занимался тем, что переносил довольно боьшие проекты под разные платформы. ЧУЖИЕ проекты. И находил там просто тонны ошибок. В частности все эти гарантии безопасности при исключительных ситуациях -- филькина грамота. В реальном коде они НЕ ОБЕСПЕЧИВАЮТСЯ. Это такое вот моё эксперементальное наблюдение.
    И в моём, скорее всего тоже. Это просто слишком трудно верефицируемое свойство кода, что бы можно было его гарантировать...

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

    Ой, ищи виновников чего хочешь, где придумаешь.
    Я всего лишь делюсь опытом, и предлагаю тебе небольшой эксперимент.
    Если ты так уж уверен в своём проекее, то в чём проблема? С чего вся эта попаболь?..
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[36]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 08:51
    Оценка:
    Здравствуйте, Patalog, Вы писали:

    P>Если ограничиваться только данным куском и вводными то OnInit'y ничего другого кроме как

    P>
    P>try
    P>{ ReadProfile(name); }
    P>catch (profile_error const&)
    P>{ CreateNewProfile(name); }
    P>

    P>не остается.
    P>Если посмотреть на задачу немножко более подробно — все может сложиться иначе (с)

    Так вы не уточнили какой вариант предпочли бы лично вы...
    Re[35]: Это-то как раз просто решается...
    От: niXman Ниоткуда https://github.com/niXman
    Дата: 26.02.13 08:52
    Оценка:
    Здравствуйте, Erop, Вы писали:

    E>Я тебе ещё раз говорю, что несколько лет занимался тем, что переносил довольно боьшие проекты под разные платформы. ЧУЖИЕ проекты. И находил там просто тонны ошибок. В частности все эти гарантии безопасности при исключительных ситуациях -- филькина грамота. В реальном коде они НЕ ОБЕСПЕЧИВАЮТСЯ.

    это просто слова.
    велкам
    Автор: niXman
    Дата: 26.02.13
    .

    E>С чего вся эта попаболь?..

    нет никаких переживаний. просто я люблю понимать истинные причины а не те, которые люди пытаются выдать за таковые. как правило.
    пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
    Re[36]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 08:53
    Оценка:
    Здравствуйте, MTD, Вы писали:

    MTD>Очевидно это те ошибки которые нельзя обработать на данном уровне и игнорирование которых делает дальнейшую работу программы бессмысленной.


    Подпишусь под этой формулировкой.

    И при этом замечу, что если следовать ей, то на исключения выпадает совсем небольшая часть общей массы обработки ошибок.
    Re[33]: Это-то как раз просто решается...
    От: Erop Россия  
    Дата: 26.02.13 08:57
    Оценка:
    Здравствуйте, niXman, Вы писали:

    X>решение несуществующих проблем мне мало интересно. но обработка С++ ошибок в Си-стиле, всегда более запутанная и "дырявая". и это факт.


    А что значит "дырявая", и что значит "в С стиле"?
    Я тут где-то писал как на мой взгляд стоит использовать исключения...
    И как можно от них рпри этом отказаться, если это зачем-то надо...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[25]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 26.02.13 09:00
    Оценка:
    Здравствуйте, Patalog, Вы писали:

    P>Вполне возможно.

    P>Мой поинт в том, что тот уровень обработки ошибок, который обеспечивает "сферический программист в вакууме" за которого так болеет тролльErop, с помощью исключений обеспечивается проще и приятнее.
    P>Ясное дело, когда начинаются holy wars, все внезапно пишут код не иначе как для "ядерных реакторов" (tm), и начинают сыпать терминами про вилидность\верифицируемость\гарантии etc.

    Совсем запутал. Так надо тартить усилия на обеспчение базового уровня гарантий безопасности ВСЕГО КОДА или нет?..
    Если надо, то пофиг на то, какой уровень обработки ошибок мы там обеспечили. Проблема не в том, что мы там что-то обеспенчили или не обеспечили, чего может и не случится вовсе, а в том, что мы потратили много усилий не пойми на что. И именно эти вот доп. усилия и пессимизацию и надо сравнивать с доп. усилиями и пессимизацией в других подходах. А не мифическую производительность обработки исключений...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[34]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 26.02.13 09:04
    Оценка: 4 (2) +1 -1
    Здравствуйте, Patalog, Вы писали:

    P>1. Зачем его переписывать через исключения, что було?

    P>Если ты можешь обработать "ошибку" на этом уровне, ее и нужно там обработать. Для данного случая это не ошибка, это нормальная ситуация.
    P>Исключением это будет если ты на этом уровне не можешь вызвать CreateNewProfile, тогда логично кинуть исключение,
    P>которое поймает тот уровень который может сделать CreateNewProfile.


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

    "Неотлаживаемое" тут обозначает, что что-то гавкается, потом это как-то где-то неведомо где и как 2обрабатывается", в результате гавкается ещё что-то малопредсказуемое, и когда наконец-то мы получаем какое-то наблюдаемое поведение до исходной причины уже не добраться.
    Лапша из goto времён спагети-кода просто полнейшая халява по сравнению с этой обработкой исключений "на подходящем уровне"
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[35]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 26.02.13 09:06
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    _>Ошибки выделения памяти видимо. А ещё что? )


    Самое обидное, что как раз вот ошибки выделения памяти через исключения обрабатывать неудобно. Казалось бы всё хорошо, но типичный обработчик исключения в типичной программе сам чегой-то аллокирует. В логи там пишет, окошки кажет и т. д... А памяти-то нет, так что всё радостно валится дальше совершенно малопонимабельным образом...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[36]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 26.02.13 09:08
    Оценка:
    Здравствуйте, Tanker, Вы писали:

    T>Исключения нужны для того, что бы код обработки ошибок был в одном месте, а не везде по коду. Скажем это может быть публичный метод компонента. Глубина вызовов из этого метода может быть сколь угодно большой, это не создает никаких проблем для исключений.


    Так, этот подход мне нравится намного больше. Теперь осталось разобраться ещё с гарантиями безопасности при исключениях. Так ли уж нужна базовая гарантия?
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[37]: Вот еще, или я, кажется, читать разучился
    От: jazzer Россия Skype: enerjazzer
    Дата: 26.02.13 09:11
    Оценка: +1
    Здравствуйте, alex_public, Вы писали:

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


    MTD>>Очевидно это те ошибки которые нельзя обработать на данном уровне и игнорирование которых делает дальнейшую работу программы бессмысленной.


    _>Подпишусь под этой формулировкой.


    _>И при этом замечу, что если следовать ей, то на исключения выпадает совсем небольшая часть общей массы обработки ошибок.


    Правда? Это только в двухстрочных примерах все так хорошо и разницы не видно.
    А на самом деле внутри твоей функции ReadProfile зовется еще 50 функций на 10 уровнях вложенности. И ни одна из них, заметь, не способна обработать ошибку на своем уровне, и ей остается лишь передать ошибку на верхний уровень, который способен принять решение "Не считалось? Ну и хрен с ним, создадим новый".
    Так что твой пример с загрузкой чего-то сложного хз откуда — это как раз идеальный пример кода, в котором исключения работают просто офигительно. Потому что любая ошибка в процессе загрузки фатальна для этого самого процесса загрузки и может быть обработано лишь на самом верхнем уровне, откуда пришел приказ загружать.
    А такой порядок работы можно гарантировать только исключениями.
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[41]: Вот еще, или я, кажется, читать разучился
    От: Tanker  
    Дата: 26.02.13 09:17
    Оценка: -1
    Здравствуйте, alex_public, Вы писали:

    _>Кстати, а как вам точка зрения этих нескольких человек выше по темке, что мол этот случай не имеет никакого отношения к исключениям и соответственно его надо обрабатывать через коды возврата?


    Очень просто — в С++ не смотря на слова try catch throw нет полноценных исключений. Нет слова leave, нет слова finally, зато есть неприятные особенности деструкторов и раскрутки исключений.
    Лично я встречал и не раз, когда деструктор вызывает какую то логику финализации и один из методов из этой логики после какого то фикса вдруг начинает бросать исключения, что даёт недокументированый Terminate.
    The animals went in two by two, hurrah, hurrah...
    Re[36]: Вот еще, или я, кажется, читать разучился
    От: jazzer Россия Skype: enerjazzer
    Дата: 26.02.13 09:21
    Оценка: :)
    Здравствуйте, Erop, Вы писали:

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


    _>>Ошибки выделения памяти видимо. А ещё что? )


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


    Ну, прибегая к твоей любимой тактике ведения дискуссии, я готов поверить, что в вашей команде подходят так наивно к обработке ошибки выделения памяти и имеют из-за этого проблемы, но не надо распространять этот детский опыт на всех.
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[37]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 26.02.13 09:28
    Оценка:
    Здравствуйте, jazzer, Вы писали:

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

    J>

    А что делают все? Сдувают подушку?
    Исключения они же того, ещё и стек свернут, а при этом много чего позваться может...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[35]: Вот еще, или я, кажется, читать разучился
    От: andyp  
    Дата: 26.02.13 09:35
    Оценка: 1 (1) :)
    Здравствуйте, Erop, Вы писали:

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


    P>>1. Зачем его переписывать через исключения, что було?

    P>>Если ты можешь обработать "ошибку" на этом уровне, ее и нужно там обработать. Для данного случая это не ошибка, это нормальная ситуация.
    P>>Исключением это будет если ты на этом уровне не можешь вызвать CreateNewProfile, тогда логично кинуть исключение,
    P>>которое поймает тот уровень который может сделать CreateNewProfile.


    E>Это, кстати, ещё одна большая проблема исключений. Когда их начинают обрабатывать не помйми кто когда и где. Большой проект быстро превращается в абсолютно неотлаживоемое УГ..


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

    E>Лапша из goto времён спагети-кода просто полнейшая халява по сравнению с этой обработкой исключений "на подходящем уровне"

    Мои 5 копеек — тоже много раз видел этот чудесный стиль "я кинул и я молодец". Люди не хотят думать об обработке ошибок используя вместо этого прочитанный в книжках "универсальный" подход, к тому же позволяющий избежать гемороя с продумыванием того, что делать с ошибкой. Типа там сверху виднее будет. Часто бывает так, что поймавший просто не знает что делать с ошибкой. Просто кинуть — не значит обработать.

    Я часто всякую математику пишу. Есть "классная" мысль — кидать domain_error, если не попал в область определения функции (ну например корень из отрицательного числа пытаешься подсчитать). Так вот, не понятно, что с этим исключением делать на верхнем уровне после вызовов 100500 корней внизу. Но чел считает, что он ошибки обрабатывает, ведь кинул, чо. В результате — УГ и отладка за автора.
    Re[38]: Вот еще, или я, кажется, читать разучился
    От: jazzer Россия Skype: enerjazzer
    Дата: 26.02.13 09:41
    Оценка: :)
    Здравствуйте, Erop, Вы писали:

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


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

    J>>

    E>А что делают все? Сдувают подушку?

    Именно. Сдувают предварительно надутую подушку.

    E>Исключения они же того, ещё и стек свернут, а при этом много чего позваться может...

    "Много чего" должно учитываться при выборе размера подушки.
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[36]: Вот еще, или я, кажется, читать разучился
    От: Tanker  
    Дата: 26.02.13 09:45
    Оценка: +2
    Здравствуйте, Erop, Вы писали:

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


    Типичный обработчик обрабатывает конкретную ошибку, а не все подряд. Во первых, если все тухло, то спасать уже нечего. Во вторых, если чего то спасти можно, то обработчик нехватки памяти как раз ничего и не выделяет, для него пишется специальный случай и вызывать будет чз catch(OutOfMemory ex).
    Представь, без исключений нужно все аллокации проверять вот так
    MyClass *pInstance = new MyClass();
    
    if(!pInstance)
    {
    /// И чо ? Прямо здесь, как правило, нет возможности обработать эту ошибку и надо транслировать на самый верх, то есть все функции вверх по стеку должны знать про это
    /// Как правило, только на самом верху появляется возможность обработать именно OutOfMemory
    }

    При чем так должен делать не только твой, но и чужой код, типа бустов, стл и тд.
    Самое главное — в итоге, когда все это приобретет законченый вид, вдруг оказывается, что код обработки ошибок делает ровно то же, что и исключения, только явно.
    The animals went in two by two, hurrah, hurrah...
    Re[38]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 10:05
    Оценка: +1 -2
    Здравствуйте, jazzer, Вы писали:

    J>Правда? Это только в двухстрочных примерах все так хорошо и разницы не видно.

    J>А на самом деле внутри твоей функции ReadProfile зовется еще 50 функций на 10 уровнях вложенности. И ни одна из них, заметь, не способна обработать ошибку на своем уровне, и ей остается лишь передать ошибку на верхний уровень, который способен принять решение "Не считалось? Ну и хрен с ним, создадим новый".

    Описаны очень чёткие симптомы кривой и не модульной изначальной архитектуры.

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

    J>А такой порядок работы можно гарантировать только исключениями.

    Хыхыхы, а уже куча народа в этой темке (в том числе и сторонники исключений) уверенно заявила что мой пример даже близко не имеет никакого отношения к исключениям.
    Re[42]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 10:09
    Оценка: -1
    Здравствуйте, Tanker, Вы писали:

    T>Очень просто — в С++ не смотря на слова try catch throw нет полноценных исключений. Нет слова leave, нет слова finally, зато есть неприятные особенности деструкторов и раскрутки исключений.

    T>Лично я встречал и не раз, когда деструктор вызывает какую то логику финализации и один из методов из этой логики после какого то фикса вдруг начинает бросать исключения, что даёт недокументированый Terminate.

    Нуу в каком-то смысле в C++ заменой finally и т.п. могут быть просто {} скобки... Но в целом да, соглашусь, что цельной системы нет.
    Re[37]: Вот еще, или я, кажется, читать разучился
    От: Patalog Россия  
    Дата: 26.02.13 10:22
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    []

    _>Так вы не уточнили какой вариант предпочли бы лично вы...


    Для этого мне не достаточно информации.
    Почетный кавалер ордена Совка.
    Re[39]: Вот еще, или я, кажется, читать разучился
    От: Patalog Россия  
    Дата: 26.02.13 10:28
    Оценка: +1 :)
    Здравствуйте, alex_public, Вы писали:

    хъ

    _>Хыхыхы, а уже куча народа в этой темке (в том числе и сторонники исключений) уверенно заявила что мой пример даже близко не имеет никакого отношения к исключениям.


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

    ЗЫ Судя по всему тебе не интересно обсуждение, тебе интересно погыгыкать.
    Почетный кавалер ордена Совка.
    Re[26]: Вот еще, или я, кажется, читать разучился
    От: Patalog Россия  
    Дата: 26.02.13 11:16
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    хъ

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


    Я не понимаю, что значит "должны приводить к глубокой раскрутке стека". Ошибки никому ничего не должны, наоборот их должны обрабатывать.
    Кто, как и где — вопрос выбора в каждом конкретном случае, я лично затрудняюсь дать общие рекомендации.
    Возвращаясь к своему примеру анализатора входных данных под заданную спецификацию формата —
    парсим нек. заголовок -> опс, нарушение констрейнов (значение должно быть меньше Х) -> обработка — добавляем к списку ошибок
    парсим нек. заголовок -> опс, по нек. признакам делаем вывод что это говно какое-то -> исключение -> на уровне где происходит отделение мух от котлет, ловим, записываем и пытаемся пересинхронизироваться, т.е. найти след. sync word. Пытаться обработать ошибку на том же кровне где мы поняли что данные тотально "не те" — значить пытаться упорно найти нужным нам заголовок не понятно из чего, забить список ошибок нерелевантными сообщениями и обтормозить весь процесс. Пытаться там же пересинхронизироваться — размывать логику разбора, размывать ответственность, протаскивать ненужный контекст.

    _>Для большинства же случаев (а чаще всего какая-то минимальная обработка ошибок идёт уже на предыдущем уровне стека вызовов) на практике исключения привносят только увеличение сложности и объёма кода.


    Практика конечно у всех разная, у меня не было прецендентов усложнения из-за исключений. Обратные преценденты были.
    В том числе и с "заменой кодов возврата" (что в принципе порицается) — нужно было протаскивать коды возврата из 3d party, из самой глубины на самый вверх, вплоть до JS скрипта живущего на хтмл странице. Я выкинул всю гору лапши /if(e) return e;/ по всему стеку вызовов (довольно глубоких) и заменил на throw класса который хранит код ошибки (если точнее это boost::system::system_error). Чем очень облегчил себе жизнь и _уменьшил_ объем кода.
    Почетный кавалер ордена Совка.
    Re[37]: Вот еще, или я, кажется, читать разучился
    От: minorlogic Украина  
    Дата: 26.02.13 11:35
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    _>И при этом замечу, что если следовать ей, то на исключения выпадает совсем небольшая часть общей массы обработки ошибок.


    Так и источников ошибок на самом деле не так много. А все остальное это логика работы она же управляющая логика. Обычно управляющая логика обменивается результатами сквозь 1 уровень и имеет жесткую смысловую нагрузку.
    ... << RSDN@Home 1.2.0 alpha 5 rev. 1539>>
    Ищу работу, 3D, SLAM, computer graphics/vision.
    Re[34]: Вот еще, или я, кажется, читать разучился
    От: landerhigh Пират  
    Дата: 26.02.13 12:24
    Оценка:
    Здравствуйте, Erop, Вы писали:

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


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


    E>Во-первых, при чём тут я?


    Потому что это твои слова.

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


    Тройной фейспалм.

    E>В частности, в таких проектах принято использозвать такую библиотеку assert'ов, которая обеспечивает выполнение проверок и в продакшин сборке. При этом обработка провала assert'а состоит не в вызове terminate, а в чём-то более хитром...


    Бесконечный фейспалм.

    E>Но в целом ты же умыл руки? И правильно сделал, по существу-то ты так ничего и не сказал, между прочим


    По существу мы как раз от тебя ничего не дождались.
    www.blinnov.com
    Re[32]: Интересно, как ты понимаешь фразу "могу доказать"?..
    От: landerhigh Пират  
    Дата: 26.02.13 12:28
    Оценка:
    Здравствуйте, Erop, Вы писали:


    E>Ты врде как сообщил тут, что в общем случае кидающего move-конструктора невозможно соблюсти базовую гарантию для вектора. При этом грозился доказать в три строчки...


    E>Можешь привести доказательство, или это было так, фигурально выражаясь, так сказать?..


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

    А то ведь на деле может оказаться, что доказательство для твоего случая будет намного короче трех строк.
    www.blinnov.com
    Re[42]: Вот еще, или я, кажется, читать разучился
    От: Nikе Россия  
    Дата: 26.02.13 12:33
    Оценка: :)
    Здравствуйте, Tanker, Вы писали:

    T>Очень просто — в С++ не смотря на слова try catch throw нет полноценных исключений.

    Есть.

    T>Нет слова leave, нет слова finally

    Они не нужны с RAII.

    T>зато есть неприятные особенности деструкторов и раскрутки исключений.

    Это да, неприятно.

    T>Лично я встречал и не раз, когда деструктор вызывает какую то логику финализации и один из методов из этой логики после какого то фикса вдруг начинает бросать исключения, что даёт недокументированый Terminate.


    Правда ИМХО возникновение таких неприятностей является симптомом косого подхода к генерации кода. Не встречал лично.
    Нужно разобрать угил.
    Re[33]: Вот еще, или я, кажется, читать разучился
    От: landerhigh Пират  
    Дата: 26.02.13 12:49
    Оценка:
    Здравствуйте, alex_public, Вы писали:


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


    Объект Шредингера после вызова конструктора — это, конечно, треш и угар. Но тут и обсуждать нечего — только в переплавку.

    По поводу исключений из конструктора: конструктор объекта обязан выкинуть исключение, как только возникает ситуация, делающее существование объекта бессмысленным. Это бывает далеко не так часто, но вовсе не ограничивается обломом с выделением памяти. Например — вектор без памяти никому не нужен. Класс FileLogger на машине без доступной для записи файловой системы тоже. OpenGLRenderer никому не нужен, если нет его поддержки. И так далее. Но все это — именно исключительные ситуации; полагаться исключительно на исключения для обработки таких ошибок не следует, это в некотором смысле последняя линия обороны.
    www.blinnov.com
    Re[43]: Вот еще, или я, кажется, читать разучился
    От: Tanker  
    Дата: 26.02.13 13:05
    Оценка:
    Здравствуйте, Nikе, Вы писали:

    T>>Очень просто — в С++ не смотря на слова try catch throw нет полноценных исключений.

    N>Есть.

    T>>Нет слова leave, нет слова finally

    N>Они не нужны с RAII.

    С++ это не только RAII.

    T>>зато есть неприятные особенности деструкторов и раскрутки исключений.

    N>Это да, неприятно.

    И это называется полноценные исключения ?

    T>>Лично я встречал и не раз, когда деструктор вызывает какую то логику финализации и один из методов из этой логики после какого то фикса вдруг начинает бросать исключения, что даёт недокументированый Terminate.


    N>Правда ИМХО возникновение таких неприятностей является симптомом косого подхода к генерации кода. Не встречал лично.


    Как послушать местных плюсовиков, так все в шоколаде — код чисто RAII и пишут его люди от 10 лет и выше опытом.
    The animals went in two by two, hurrah, hurrah...
    Re[44]: Вот еще, или я, кажется, читать разучился
    От: Nikе Россия  
    Дата: 26.02.13 13:22
    Оценка: +3
    Здравствуйте, Tanker, Вы писали:

    T>>>Нет слова leave, нет слова finally

    N>>Они не нужны с RAII.

    T>С++ это не только RAII.


    Ты это к чему? Тезис — при использовании RAII finally не нужен. Причём тут "С++ это не только RAII"?

    T>>>зато есть неприятные особенности деструкторов и раскрутки исключений.

    N>>Это да, неприятно.

    T>И это называется полноценные исключения ?


    Ну да. Есть разумое ограничение. Это не делает исключения неполноценными.

    T>>>Лично я встречал и не раз, когда деструктор вызывает какую то логику финализации и один из методов из этой логики после какого то фикса вдруг начинает бросать исключения, что даёт недокументированый Terminate.


    N>>Правда ИМХО возникновение таких неприятностей является симптомом косого подхода к генерации кода. Не встречал лично.


    T>Как послушать местных плюсовиков, так все в шоколаде — код чисто RAII и пишут его люди от 10 лет и выше опытом.


    Причём тут это? Ты хочешь пообсуждать некомпетентных разработчиков?
    Нужно разобрать угил.
    Re[43]: Вот еще, или я, кажется, читать разучился
    От: Evgeny.Panasyuk Россия  
    Дата: 26.02.13 13:24
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    _>Нуу в каком-то смысле в C++ заменой finally и т.п. могут быть просто {} скобки...


    В каком смысле "просто {} скобки" заменяют finally?
    Re[45]: Вот еще, или я, кажется, читать разучился
    От: Tanker  
    Дата: 26.02.13 13:43
    Оценка:
    Здравствуйте, Nikе, Вы писали:

    N>Ты это к чему? Тезис — при использовании RAII finally не нужен. Причём тут "С++ это не только RAII"?


    Если речь про С++ то вполне понятно, что при чем. А если выбирать удобное подмножество типа C++ && RAII то может оказаться что и виртуальные методы не нужны.

    T>>Как послушать местных плюсовиков, так все в шоколаде — код чисто RAII и пишут его люди от 10 лет и выше опытом.


    N>Причём тут это? Ты хочешь пообсуждать некомпетентных разработчиков?


    см выше.
    The animals went in two by two, hurrah, hurrah...
    Re[39]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 26.02.13 13:45
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    E>>А что делают все? Сдувают подушку?

    J>Именно. Сдувают предварительно надутую подушку.
    Бинго! А что они делают, когда памяти не хватает во второй раз?
    Чем это вообще отличается от старой доброй сишной схемы?

    J>"Много чего" должно учитываться при выборе размера подушки.

    Э-э-э, это не всегда просто учесть, однако таки...

    Тут схема, когда отгрузку/рестарт по нехватке памяти мы прописываем явно намного прямее
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[46]: Вот еще, или я, кажется, читать разучился
    От: Nikе Россия  
    Дата: 26.02.13 13:48
    Оценка: +1 :)
    Здравствуйте, Tanker, Вы писали:

    N>>Ты это к чему? Тезис — при использовании RAII finally не нужен. Причём тут "С++ это не только RAII"?


    T>Если речь про С++ то вполне понятно, что при чем. А если выбирать удобное подмножество типа C++ && RAII то может оказаться что и виртуальные методы не нужны.


    Не распрасил. По моему ты мутишь.
    Нужно разобрать угил.
    Re[37]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 26.02.13 13:50
    Оценка: -1 :)
    Здравствуйте, Tanker, Вы писали:

    T>Типичный обработчик обрабатывает конкретную ошибку, а не все подряд. Во первых, если все тухло, то спасать уже нечего.

    Обычно хотят спасти данные пользователя + получить адекватную отладочную инфу...

    T>При чем так должен делать не только твой, но и чужой код, типа бустов, стл и тд.

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

    Почему7 В С же как-то жили? По доступу к нулю будет сегфолт, в его обработчике спасут критические данные и запишут в корку отладочную инфу...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[44]: Вот еще, или я, кажется, читать разучился
    От: Nikе Россия  
    Дата: 26.02.13 13:52
    Оценка:
    Здравствуйте, Evgeny.Panasyuk, Вы писали:

    _>>Нуу в каком-то смысле в C++ заменой finally и т.п. могут быть просто {} скобки...


    EP>В каком смысле "просто {} скобки" заменяют finally?


    Деструкторы обязательно отработают -> finally не нужен.
    Нужно разобрать угил.
    Re[40]: Вот еще, или я, кажется, читать разучился
    От: jazzer Россия Skype: enerjazzer
    Дата: 26.02.13 14:01
    Оценка:
    Здравствуйте, Erop, Вы писали:

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


    E>>>А что делают все? Сдувают подушку?

    J>>Именно. Сдувают предварительно надутую подушку.
    E>Бинго! А что они делают, когда памяти не хватает во второй раз?
    Такого не будет. Приложение входит в режим завершения и корректно выключается.
    Памяти на логирование хватит.

    E>Чем это вообще отличается от старой доброй сишной схемы?


    J>>"Много чего" должно учитываться при выборе размера подушки.

    E>Э-э-э, это не всегда просто учесть, однако таки...
    На логирование хватит.

    E>Тут схема, когда отгрузку/рестарт по нехватке памяти мы прописываем явно намного прямее

    Куда уж прямее
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[35]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 26.02.13 14:01
    Оценка:
    Здравствуйте, landerhigh, Вы писали:

    L>По существу мы как раз от тебя ничего не дождались.

    ищите и обрящете...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[45]: Вот еще, или я, кажется, читать разучился
    От: Evgeny.Panasyuk Россия  
    Дата: 26.02.13 14:02
    Оценка:
    Здравствуйте, Nikе, Вы писали:

    _>>>Нуу в каком-то смысле в C++ заменой finally и т.п. могут быть просто {} скобки...

    EP>>В каком смысле "просто {} скобки" заменяют finally?
    N>Деструкторы обязательно отработают -> finally не нужен.

    да не, товарищ точно что-то другое имел ввиду — он же говорит про какие-то "просто {} скобки".
    Re[38]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 26.02.13 14:07
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>А на самом деле внутри твоей функции ReadProfile зовется еще 50 функций на 10 уровнях вложенности. И ни одна из них, заметь, не способна обработать ошибку на своем уровне, и ей остается лишь передать ошибку на верхний уровень, который способен принять решение "Не считалось? Ну и хрен с ним, создадим новый".

    Ну то есть мы возвращаемся к исходному тезису "а что же такое ошибка?"
    Вот в тех 50 ыункциях, например, будет поиск каталога, открытие файла, чтение даных, их разбор.
    Что будет из этого кидать исключения? провалившееся открытиые файла? Устаревшая версия формата данных в файле? В смысле разборщик данных, задетективший устаревшую версию? Что-то ещё?..
    Фишка-то как раз в том, что пока мы не можем обработтать особую ситуацию мы обычно не знаем ошибка это или штатная версия поведения кода. А там, где уже знаем, обычно и обработать можем...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[36]: Вот еще, или я, кажется, читать разучился
    От: MTD https://github.com/mtrempoltsev
    Дата: 26.02.13 14:12
    Оценка: 1 (1)
    Здравствуйте, Erop, Вы писали:

    L>>По существу мы как раз от тебя ничего не дождались.

    E>ищите и обрящете...

    Не стоит искать смысл, там где его нет. У меня сложилось мнение, что в данной теме ты просто троллишь, выдумываешь сферических коней и просишь их обосновать.
    Re[41]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 26.02.13 14:17
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>Такого не будет. Приложение входит в режим завершения и корректно выключается.

    J>Памяти на логирование хватит.

    На кой для этого вообще исключения, а не exit, например?..
    E>>Чем это вообще отличается от старой доброй сишной схемы?

    E>>Тут схема, когда отгрузку/рестарт по нехватке памяти мы прописываем явно намного прямее

    J>Куда уж прямее

    Ну прямее, это когда мы по onexit или какому-то аналогу регим чего нам аварийно надо спасти в случае если уже пора, а потом просто зовём exit или аналог и всё...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[37]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 26.02.13 14:18
    Оценка:
    Здравствуйте, MTD, Вы писали:

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


    Если ты не заметил, я задал простой вопрос. На кой нужна базовая гарантия...
    Ответов пока не наблюдаю.
    Да, мой от вет прост -- она не нужна.
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[38]: Вот еще, или я, кажется, читать разучился
    От: Tanker  
    Дата: 26.02.13 14:37
    Оценка:
    Здравствуйте, Erop, Вы писали:

    T>>Типичный обработчик обрабатывает конкретную ошибку, а не все подряд. Во первых, если все тухло, то спасать уже нечего.

    E>Обычно хотят спасти данные пользователя + получить адекватную отладочную инфу...

    На этот случай делается подушка + специальный режим работы, который работает медленно но максимально надежно.

    T>>При чем так должен делать не только твой, но и чужой код, типа бустов, стл и тд.

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

    E>Почему7 В С же как-то жили? По доступу к нулю будет сегфолт, в его обработчике спасут критические данные и запишут в корку отладочную инфу...


    В С++ это тоже возможно.
    The animals went in two by two, hurrah, hurrah...
    Re[39]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 26.02.13 14:42
    Оценка:
    Здравствуйте, Tanker, Вы писали:

    E>>Почему7 В С же как-то жили? По доступу к нулю будет сегфолт, в его обработчике спасут критические данные и запишут в корку отладочную инфу...


    T>В С++ это тоже возможно.


    Конечно возможно.
    Просто, если помнишь, я высказал сожаление, что хотя вот нехватка памяти как раз такое событие, для исключений, но его прямее получается обрабатывать в чисто сишном ключе...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[39]: Вот еще, или я, кажется, читать разучился
    От: jazzer Россия Skype: enerjazzer
    Дата: 26.02.13 14:57
    Оценка: +1 :)
    Здравствуйте, Erop, Вы писали:

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


    J>>А на самом деле внутри твоей функции ReadProfile зовется еще 50 функций на 10 уровнях вложенности. И ни одна из них, заметь, не способна обработать ошибку на своем уровне, и ей остается лишь передать ошибку на верхний уровень, который способен принять решение "Не считалось? Ну и хрен с ним, создадим новый".

    E>Ну то есть мы возвращаемся к исходному тезису "а что же такое ошибка?"
    Ага, причем тезис был мой

    E>Вот в тех 50 ыункциях, например, будет поиск каталога, открытие файла, чтение даных, их разбор.

    E>Что будет из этого кидать исключения? провалившееся открытиые файла? Устаревшая версия формата данных в файле? В смысле разборщик данных, задетективший устаревшую версию? Что-то ещё?..
    E>Фишка-то как раз в том, что пока мы не можем обработтать особую ситуацию мы обычно не знаем ошибка это или штатная версия поведения кода. А там, где уже знаем, обычно и обработать можем...
    Вот там, где знаем, там и обрабатываем исключения или пользуемся небросающим интерфейсом (но к исключениям в любом случае надо быть готовым).
    Логика очень простая: функция должна выполнить некое задание, которое ей дает вызывающий код.
    Если она это задание выполнить не может, она бросает исключение.
    Вот и все.
    Соответственно функция ReadProfile при проблеме с файлом не может выполнить приказ "прочитать профиль из файла" и бросает исключение.
    А функция ReadProfileOrCreateNew — может наплевать на файл, если с ним что-то не так, и попробовать создать новый профиль. Но если с новым профилем тоже облом выйдет — она тоже бросит исключение, которое будет означать "не смогла ни прочитать, ни новый создать".
    Т.е. open_file(path) должна бросать исключение, если файла нет. Но при этом может параллельно существовать небросающий интерфейс, например, bool file_can_be_open(path, mode), bool path_is_well_formed(path).
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[40]: Вот еще, или я, кажется, читать разучился
    От: Tanker  
    Дата: 26.02.13 14:58
    Оценка: :)
    Здравствуйте, Erop, Вы писали:

    E>Конечно возможно.

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

    По твоему исключения SEH, как ты предложил, это сишный подход ? Т.е. ты видишь серьезные отличие между try catch и __try __except ? Я даже и не знаю, как быть.
    The animals went in two by two, hurrah, hurrah...
    Re[42]: Вот еще, или я, кажется, читать разучился
    От: jazzer Россия Skype: enerjazzer
    Дата: 26.02.13 15:15
    Оценка:
    Здравствуйте, Erop, Вы писали:

    E>Ну прямее, это когда мы по onexit или какому-то аналогу регим чего нам аварийно надо спасти в случае если уже пора, а потом просто зовём exit или аналог и всё...


    Все правильно. Для этого в С++ есть set_new_handler.
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[40]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 17:35
    Оценка: +1 :)
    Здравствуйте, Patalog, Вы писали:

    P>ЗЫ Судя по всему тебе не интересно обсуждение, тебе интересно погыгыкать.


    На самом деле я просто смотрю сколько народа готово использовать исключения даже в приведённом мною случае. И каждый высказавшийся за это увеличивает моё согласие с решением разных компаний забанить исключения в целом. Понятна моя мысль? )
    Re[27]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 17:42
    Оценка:
    Здравствуйте, Patalog, Вы писали:

    P>Я не понимаю, что значит "должны приводить к глубокой раскрутке стека". Ошибки никому ничего не должны, наоборот их должны обрабатывать.


    См. ниже.

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

    P>Возвращаясь к своему примеру анализатора входных данных под заданную спецификацию формата -
    P>парсим нек. заголовок -> опс, нарушение констрейнов (значение должно быть меньше Х) -> обработка — добавляем к списку ошибок
    P>парсим нек. заголовок -> опс, по нек. признакам делаем вывод что это говно какое-то -> исключение -> на уровне где происходит отделение мух от котлет, ловим, записываем и пытаемся пересинхронизироваться, т.е. найти след. sync word. Пытаться обработать ошибку на том же кровне где мы поняли что данные тотально "не те" — значить пытаться упорно найти нужным нам заголовок не понятно из чего, забить список ошибок нерелевантными сообщениями и обтормозить весь процесс. Пытаться там же пересинхронизироваться — размывать логику разбора, размывать ответственность, протаскивать ненужный контекст.

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

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

    P>В том числе и с "заменой кодов возврата" (что в принципе порицается) — нужно было протаскивать коды возврата из 3d party, из самой глубины на самый вверх, вплоть до JS скрипта живущего на хтмл странице. Я выкинул всю гору лапши /if(e) return e;/ по всему стеку вызовов (довольно глубоких) и заменил на throw класса который хранит код ошибки (если точнее это boost::system::system_error). Чем очень облегчил себе жизнь и _уменьшил_ объем кода.

    Вот вы написали что не понимаете про глубину стека и тут же приводите буквально идеальный пример этого. Причём замечу что даже с использование того же слова ("протаскивать коды возврата из самой глубины на самый вверх"). У вас как раз тот самый необычный случай, когда вся обработка идёт только на самом высоком уровне — идеальное применение исключений.
    Re[38]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 17:47
    Оценка:
    Здравствуйте, minorlogic, Вы писали:

    M>Так и источников ошибок на самом деле не так много. А все остальное это логика работы она же управляющая логика. Обычно управляющая логика обменивается результатами сквозь 1 уровень и имеет жесткую смысловую нагрузку.


    Конечно. Просто частенько говорят что-то вроде "функция возвращает ошибку в случае неудачи". Хотя в контексте исполнения программы это совсем не ошибка даже. Это вопрос так сложившейся терминологии...
    Re[39]: Вот еще, или я, кажется, читать разучился
    От: minorlogic Украина  
    Дата: 26.02.13 17:53
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    _>Это вопрос так сложившейся терминологии...


    Плохая терминология. Обычно это источник непонимания, я часто с этим сталкиваюсь.
    ... << RSDN@Home 1.2.0 alpha 5 rev. 1539>>
    Ищу работу, 3D, SLAM, computer graphics/vision.
    Re[34]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 17:57
    Оценка: -1 :)
    Здравствуйте, landerhigh, Вы писали:

    L>Объект Шредингера после вызова конструктора — это, конечно, треш и угар. Но тут и обсуждать нечего — только в переплавку.


    Ну да, вне зависимости от нашей дискуссии об исключениях, Tizen api всё равно останется весьма странным. )))

    L>По поводу исключений из конструктора: конструктор объекта обязан выкинуть исключение, как только возникает ситуация, делающее существование объекта бессмысленным. Это бывает далеко не так часто, но вовсе не ограничивается обломом с выделением памяти. Например — вектор без памяти никому не нужен. Класс FileLogger на машине без доступной для записи файловой системы тоже. OpenGLRenderer никому не нужен, если нет его поддержки. И так далее. Но все это — именно исключительные ситуации; полагаться исключительно на исключения для обработки таких ошибок не следует, это в некотором смысле последняя линия обороны.


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

    Жаль только с выделением памяти такой фокус не прокатывает. Точнее технические то можно (собственно new — как раз и есть такая особая функция), но тогда во-первых будет дико загромождённый код, а во-вторых обработка нехватки памяти в любом случае сводится к очень специфичным делам. Так что тут по любому исключения хороши.
    Re[44]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 18:01
    Оценка:
    Здравствуйте, Evgeny.Panasyuk, Вы писали:

    EP>В каком смысле "просто {} скобки" заменяют finally?


    В смысле деструктора. А с появлением лямбд в языке это стало совсем явно.
    Re[40]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 26.02.13 18:03
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    E>>Ну то есть мы возвращаемся к исходному тезису "а что же такое ошибка?"

    J>Ага, причем тезис был мой
    Ну тут у разных сторон есть разные ответы на этот вопрос

    J>Логика очень простая: функция должна выполнить некое задание, которое ей дает вызывающий код.

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

    J>Т.е. open_file(path) должна бросать исключение, если файла нет. Но при этом может параллельно существовать небросающий интерфейс, например, bool file_can_be_open(path, mode), bool path_is_well_formed(path).


    То, что true из file_can_be_open(path, mode), не гарантирует возможности открыть файл, так как это два РАЗНЫХ запроса, между которыми может вклиниться другой потокЪпроцесс/компьютер не смущает?..
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[40]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 18:09
    Оценка: +1 -1
    Здравствуйте, jazzer, Вы писали:

    J>Вот там, где знаем, там и обрабатываем исключения или пользуемся небросающим интерфейсом (но к исключениям в любом случае надо быть готовым).

    J>Логика очень простая: функция должна выполнить некое задание, которое ей дает вызывающий код.
    J>Если она это задание выполнить не может, она бросает исключение.
    J>Вот и все.
    J>Соответственно функция ReadProfile при проблеме с файлом не может выполнить приказ "прочитать профиль из файла" и бросает исключение.
    J>А функция ReadProfileOrCreateNew — может наплевать на файл, если с ним что-то не так, и попробовать создать новый профиль. Но если с новым профилем тоже облом выйдет — она тоже бросит исключение, которое будет означать "не смогла ни прочитать, ни новый создать".
    J>Т.е. open_file(path) должна бросать исключение, если файла нет. Но при этом может параллельно существовать небросающий интерфейс, например, bool file_can_be_open(path, mode), bool path_is_well_formed(path).

    Вы очень хорошо обосновали почему и как тут можно использовать исключения. Собственно с этим никто и не спорил. Вопрос в том зачем их тут использовать, если решение без них работает как минимум не хуже. Принцип Оккама как бы никто не отменял...
    Re[41]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 26.02.13 18:10
    Оценка:
    Здравствуйте, Tanker, Вы писали:

    T>По твоему исключения SEH, как ты предложил, это сишный подход ?

    Я где-то предлагал SEH? Это ты про сегфолт что ли? Поверх SEH можно сделать обработку похожую на сигналы, но весь SEH для этого не нужен

    T> Т.е. ты видишь серьезные отличие между try catch и __try __except ?

    Конечно вижу. Обработчик SEH может вызвать terminate() ДО раскрутки стека

    T>Я даже и не знаю, как быть.

    Ну учить мат часть, наверное?..
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[43]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 26.02.13 18:12
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>Все правильно. Для этого в С++ есть set_new_handler.


    Так я же не спорю. Я только за. Я всего лишь показываю, что вот как раз конец памяти по исключению обрабатывать стрёмно... Лучше по-сишному...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[41]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 26.02.13 18:15
    Оценка: +1
    Здравствуйте, Tanker, Вы писали:

    T>По твоему исключения SEH, как ты предложил, это сишный подход ? Т.е. ты видишь серьезные отличие между try catch и __try __except ? Я даже и не знаю, как быть.


    Нууу при определённых флагах в VC это вполне может быть одним и тем же. ))) А вообще __try __except — это всё же не C++. )))
    Re[41]: Вот еще, или я, кажется, читать разучился
    От: Patalog Россия  
    Дата: 26.02.13 19:10
    Оценка: 1 (1)
    Здравствуйте, alex_public, Вы писали:

    хъ

    _>На самом деле я просто смотрю сколько народа готово использовать исключения даже в приведённом мною случае. И каждый высказавшийся за это увеличивает моё согласие с решением разных компаний забанить исключения в целом. Понятна моя мысль? )


    Мысль предельно простая, чего ж тут не понять.
    Обоснование, правда, как это всегда бывает с простыми и ясными для понимания, но не правильными решениями, подкачало.
    Почетный кавалер ордена Совка.
    Re[28]: Вот еще, или я, кажется, читать разучился
    От: Patalog Россия  
    Дата: 26.02.13 19:39
    Оценка: 1 (1) +2
    Здравствуйте, alex_public, Вы писали:

    хъ

    _>При нормальном проектирование модульности обработка ошибок в большинстве случаев будет идти на предыдущем уровне стека вызовов.


    Это высказывание "ниачем" (с), примерно на уровне "хорошо быть богатым и красивым"
    Когда нечего сказать, начинают говорить про некое "нормальное проектирование" и т.д.
    Я привел конкретное проектное решение, где спользование исключений оправдано, ящетаю.
    Точно так же как и кодов возврата, там где это опять таки оправдано.
    Если вы не согласны — обоснуйте, если исходных данных не достаточно — спрашивайте.

    _>А в тех редких случаях, когда это не так, как раз и есть смысл использовать исключения.


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

    _>Вот вы написали что не понимаете про глубину стека и тут же приводите буквально идеальный пример этого. Причём замечу что даже с использование того же слова ("протаскивать коды возврата из самой глубины на самый вверх"). У вас как раз тот самый необычный случай, когда вся обработка идёт только на самом высоком уровне — идеальное применение исключений.


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

    И да, про глубину стека я прекрасно понимаю, я не понимаю "должны приводить" вкупе с "глубокой раскрутке стека".
    Никто никому не должен, тем более глобально. Имхо, если функция не может выполнить свой контракт при корректно заданных предусловиях, либо при этом нарушается инвариант (что в принципе то же самое) — нужно бросить исключение.
    Поглядел по диагонали на свой код — кода возврата 90% использую только в вырожденном случае (true or false) и ф-х типа validate\check etc.
    Волосы при этом мягкие и шелковистые, про глубину стека для принятия решения что применить — вспоминаю наверное в последнюю очередь, если вспоминаю вообще.
    Почетный кавалер ордена Совка.
    Re[41]: Вот еще, или я, кажется, читать разучился
    От: rusted Беларусь  
    Дата: 26.02.13 19:58
    Оценка: +2
    Здравствуйте, alex_public, Вы писали:

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


    P>>ЗЫ Судя по всему тебе не интересно обсуждение, тебе интересно погыгыкать.


    _>На самом деле я просто смотрю сколько народа готово использовать исключения даже в приведённом мною случае. И каждый высказавшийся за это увеличивает моё согласие с решением разных компаний забанить исключения в целом. Понятна моя мысль? )


    Между тем твой пример как раз демонстрирует недостатки обработки исключительных ситуаций через коды возврата: если в CreateNewProfile что-то пойдет не так, то это будет просто проигнорировано и дальнейший код будет либо пытаться работать с неполностью созданным профилем со всякими непредсказуемыми спец-эффектами либо будет перегружен проверками IsProfileValid, что и читаемость ухудшит и от производительности откушает. Да и сама ReadProfile возвращает только bool и если вышло false, то не ясно то ли это просто отсутсвие ранее сохраненного профиля (вполне ожидамая ситуация), то ли испорченнй профиль или ошибка чтения из файла ("глотать" эти ситуации создавая новый профиль может быть сильно нехорошо).

    В то же время с незабанеными исключениями этот фрагмент может выглядеть точно так же: ReadProfile так же возвращает bool, говорящий нужно ли создавать новый профиль или нет (если отсутствие профиля не является исключительной ситуацией), а в случае "чего-то не так" и ReadProfile и CreateNewProfile кидают исключения (причем где-нибудь глубоко по дереву своих вызовов).
    Re[34]: Кода мы так и не увидим, значит?..
    От: landerhigh Пират  
    Дата: 26.02.13 21:39
    Оценка: :)
    Здравствуйте, Erop, Вы писали:

    L>>Ну ты же так и ниасилил обосновать, зачем тебе нужен подобный фестиваль. Все, что мы услышали — это то, что ты "знаешь, как". Ну, знай дальше.


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


    Мания величия?

    E>Я утверждаю, что код с гарантиями будет сложнее и неэффективнее кода без гарантий. Только и всего.


    Утверждаешь — доказывай, чо.

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


    У тебя приступ шизофрении? С чего ты взял, что я тут тебе какие-то книжки пересказывать собираюсь?
    www.blinnov.com
    Re[29]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 27.02.13 01:11
    Оценка:
    Здравствуйте, Patalog, Вы писали:

    P>Видимо у меня эти случаи не такие уж и редкие. Это конечно из-за отсутствия "нормального проектирования", ясное дело.


    Это в каждом конкретном случае надо смотреть. Например ваш пример с вызовами из jscript'a похоже как раз отлично подходящий для исключений. Но не хотите же вы сказать что у вас большинство проектов по такой схеме работают?

    P>Да и вообще, народ который пользуется исключениями поголовно этим страдает. Вкупе с необычной формой мазохизма.

    P>Только некоторые отдельные товарищи стоят в позе д'Артаньяна.

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

    P>И да, про глубину стека я прекрасно понимаю, я не понимаю "должны приводить" вкупе с "глубокой раскрутке стека".

    P>Никто никому не должен, тем более глобально. Имхо, если функция не может выполнить свой контракт при корректно заданных предусловиях, либо при этом нарушается инвариант (что в принципе то же самое) — нужно бросить исключение.
    P>Поглядел по диагонали на свой код — кода возврата 90% использую только в вырожденном случае (true or false) и ф-х типа validate\check etc.
    P>Волосы при этом мягкие и шелковистые, про глубину стека для принятия решения что применить — вспоминаю наверное в последнюю очередь, если вспоминаю вообще.

    Всё очень просто и я уже даже писал кому-то здесь об этом. Вы безусловно можете применять исключения везде, вне зависимости от глубины стека вызова. Но имеет смысл их применять только для случаев обработки где-то очень далеко по стеку вызовов, т.к. в противоположном случае они просто не приносят никаких бонусов (а код при этом усложняют) по сравнению с теми же кодами возврата.
    Re[42]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 27.02.13 01:23
    Оценка:
    Здравствуйте, rusted, Вы писали:

    R>Между тем твой пример как раз демонстрирует недостатки обработки исключительных ситуаций через коды возврата: если в CreateNewProfile что-то пойдет не так, то это будет просто проигнорировано и дальнейший код будет либо пытаться работать с неполностью созданным профилем со всякими непредсказуемыми спец-эффектами либо будет перегружен проверками IsProfileValid, что и читаемость ухудшит и от производительности откушает.


    Если бы CreateNewProfile могла завершиться неудачей (неудачу выделения оперативки не считаем), то в моём коде безусловно была бы обработка соответствующей ошибки. Не надо подменять одну задачку другой — я написал именно то, что хотел написать. Хотя собственно говоря и ваш вариант задачки ничего не изменил бы в дискуссии, просто мой пример тогда бы чуть по другому выглядел.

    R>Да и сама ReadProfile возвращает только bool и если вышло false, то не ясно то ли это просто отсутсвие ранее сохраненного профиля (вполне ожидамая ситуация), то ли испорченнй профиль или ошибка чтения из файла ("глотать" эти ситуации создавая новый профиль может быть сильно нехорошо).


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

    R>В то же время с незабанеными исключениями этот фрагмент может выглядеть точно так же: ReadProfile так же возвращает bool, говорящий нужно ли создавать новый профиль или нет (если отсутствие профиля не является исключительной ситуацией), а в случае "чего-то не так" и ReadProfile и CreateNewProfile кидают исключения (причем где-нибудь глубоко по дереву своих вызовов).


    Это решение другой задачки, а не той, которую обсуждал я. И если обсудить какую-то другую изначальную логику, то я вполне могу допустить вариант, в котором исключения будут полезны. Например в случае если ошибка в функции ReadProfile на существующем профиле обязательно должна прерывать всё исполнение программы.
    Re[35]: Вот еще, или я, кажется, читать разучился
    От: landerhigh Пират  
    Дата: 27.02.13 02:41
    Оценка:
    Здравствуйте, alex_public, Вы писали:


    _>Мммм на мой взгляд правильнее решать эти задачи с точки зрения правильной архитектуры, а не таких убойных вещей как исключения. А точнее логичнее сделать у подобных классов приватный конструктор (без всяких исключений и двух фаз) и создавать их только своей функцией, которая умеет в начале проверить что все необходимые возможности железа и т.п. присутствуют.


    Это как посмотреть. Конечно, приведенные мной вещи чаще создаются через фабрики, и там для контроля ошибок возможностей море. Но это не исключает основной идеи о том, что объект, который нельзя никак использовать, не должен быть создан вообще.

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


    Есть более жизненный пример — класс "натуральная дробь". Реализация базовых операций с дробями (сложение, вычитание, умножение, деление и т.п.) Очевидно, что если значение знаменателя, переданное в конструктор такого объекта, равно нулю, то смысла в такой дроби нет. Здесь самый разумный вариант — дать по рукам выкинуть исключение.
    www.blinnov.com
    Re[39]: Вот еще, или я, кажется, читать разучился
    От: jazzer Россия Skype: enerjazzer
    Дата: 27.02.13 02:55
    Оценка: 1 (1) +3
    Здравствуйте, alex_public, Вы писали:

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


    J>>Правда? Это только в двухстрочных примерах все так хорошо и разницы не видно.

    J>>А на самом деле внутри твоей функции ReadProfile зовется еще 50 функций на 10 уровнях вложенности. И ни одна из них, заметь, не способна обработать ошибку на своем уровне, и ей остается лишь передать ошибку на верхний уровень, который способен принять решение "Не считалось? Ну и хрен с ним, создадим новый".

    _>Описаны очень чёткие симптомы кривой и не модульной изначальной архитектуры.


    Код "прямой и модульной изначальной архитектуры" на кодах возврата на в студию. С обоснованием прямизны и модульности.
    И не забывай, мы тут говорим об обработке ошибок, так что потрудись убедить нас, что ни одной ошибки случайно не пропущено и что обрабатывать ошибки кодами возврата на порядок удобнее и безопаснее, чем исключениями.
    Просим! Просим!
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[41]: Вот еще, или я, кажется, читать разучился
    От: jazzer Россия Skype: enerjazzer
    Дата: 27.02.13 02:56
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    _>Вы очень хорошо обосновали почему и как тут можно использовать исключения. Собственно с этим никто и не спорил. Вопрос в том зачем их тут использовать, если решение без них работает как минимум не хуже. Принцип Оккама как бы никто не отменял...


    Вы сначала продемонстрируйте свое "не хуже", а потом уже про бритье поговорим.
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[32]: Это-то как раз просто решается...
    От: Erop Россия  
    Дата: 27.02.13 04:31
    Оценка: :)
    Здравствуйте, Abyx, Вы писали:

    A>а тебе надо организовать приз за каждый пропущенный код ошибки.


    Зачем? Я и так знаю, что совсем избежать ошибок такого рода не получится...
    Я просто из этого знания делаю вывод, что надо выбирать такие методы программирования, для которых это нефатально...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[41]: Вот еще, или я, кажется, читать разучился
    От: jazzer Россия Skype: enerjazzer
    Дата: 27.02.13 04:48
    Оценка: 8 (1) +1
    Здравствуйте, Erop, Вы писали:

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


    E>>>Ну то есть мы возвращаемся к исходному тезису "а что же такое ошибка?"

    J>>Ага, причем тезис был мой
    E>Ну тут у разных сторон есть разные ответы на этот вопрос
    Не сомневаюсь. Но это не тот вопрос, ответ на который мы ищем. Правильный вопрос — как обрабатывать то, что ты считаешь ошибкой — кодами возврата или исключениями? Мое мнение — исключения должны быть средством по умолчанию. Коды ошибок оправданы только там, где обработка ошибок происходит постоянно на всех уровнях и является именно обработкой с несколькими ветками, а не просто пробрасыванием "if(err)return err;". Потому что такое пробрасывание — это просто закат солнца исключения вручную.

    J>>Логика очень простая: функция должна выполнить некое задание, которое ей дает вызывающий код.

    J>>Если она это задание выполнить не может, она бросает исключение.
    J>>Вот и все.
    E>То есть исключения -- это уже не ошибка, поле которой мы то ли отгружаемся, то ли сохраняемся и отгружаемся, а обычня часть интерфейса функции. Так?
    Ничего не понял, но отвечу на то, что понял: способность функции бросать исключения — это часть ее интерфейса, совершенно верно.
    Интерфейс функции — это все, что она принимает, плюс все, что она выдает обратно. Очевидно, исключения (и коды возврата) во вторую часть входят.
    Или, иными словами, то, как функция сообщает об ошибках — часть ее интерфейса. Это относится и к исключениям, и к кодам возврата.

    E>Не жалко процедурного стиля программирования и слабейшего предусловия с ним?..

    э?

    J>>Т.е. open_file(path) должна бросать исключение, если файла нет. Но при этом может параллельно существовать небросающий интерфейс, например, bool file_can_be_open(path, mode), bool path_is_well_formed(path).


    E>То, что true из file_can_be_open(path, mode), не гарантирует возможности открыть файл, так как это два РАЗНЫХ запроса, между которыми может вклиниться другой потокЪпроцесс/компьютер не смущает?..

    Очевидно, если ты предполагаешь такие гонки, надо программировать иначе
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[35]: Кода мы так и не увидим, значит?..
    От: Erop Россия  
    Дата: 27.02.13 06:37
    Оценка:
    Здравствуйте, landerhigh, Вы писали:

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

    L>Мания величия?
    В смысле? Я не думаю, что мне это нужно и не уверен, что я это смогу. При чём тут МВ?
    Или ты про себя лбимого?

    E>>Я утверждаю, что код с гарантиями будет сложнее и неэффективнее кода без гарантий. Только и всего.

    L>Утверждаешь — доказывай, чо.
    Ну, например, переаллокация буфера массива просто в лоб проще и прямее того же самого, но с гарантиями...

    L>У тебя приступ шизофрении? С чего ты взял, что я тут тебе какие-то книжки пересказывать собираюсь?


    Я не знаю, что ты собираешься, но пока что из того, что ты написал, были или просто всякие дразнилки и обижалки, или пересказ банальностей из пары книжек.
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[42]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 27.02.13 06:50
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>Не сомневаюсь. Но это не тот вопрос, ответ на который мы ищем. Правильный вопрос — как обрабатывать то, что ты считаешь ошибкой — кодами возврата или исключениями? Мое мнение — исключения должны быть средством по умолчанию.

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

    Но ты же пишешь так:
    J>>>Логика очень простая: функция должна выполнить некое задание, которое ей дает вызывающий код.
    J>>>Если она это задание выполнить не может, она бросает исключение.
    J>>>Вот и все.
    а при таком подходе умолчания неизбежно поменяются... Мы же не можем по недоступности любого файла рушить программу? Значит нам начинает требоваться более высокий уровень гарантийй безопасности при исключениях, который так же, как и "проборос" расползается по всему коду. И что из двух дешевле в разработке, автоматическом контроле, тестировании и поддержке -- вопрос крайне тонкий
    И собственно он-то и представляет интерес, а не кидание какашками или измерения накладных расходов на SEH сам по себе...

    J>Коды ошибок оправданы только там, где обработка ошибок происходит постоянно на всех уровнях и является именно обработкой с несколькими ветками, а не просто пробрасыванием "if(err)return err;". Потому что такое пробрасывание — это просто закат солнца исключения вручную.


    Даже в этом случае это не тоже самое, потому, что при кодах "проброс" происходит в явном месте алгоритма...

    J>Ничего не понял, но отвечу на то, что понял: способность функции бросать исключения — это часть ее интерфейса, совершенно верно.

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

    На мой взгляд объединять их в один глупо.

    J>Интерфейс функции — это все, что она принимает, плюс все, что она выдает обратно. Очевидно, исключения (и коды возврата) во вторую часть входят.

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

    J>Или, иными словами, то, как функция сообщает об ошибках — часть ее интерфейса. Это относится и к исключениям, и к кодам возврата.


    Возможно я отстал и уже придумали, как обработку исклчений запихать в weekest_precondition, если это так -- поделись, пожалуйста, если нет, то ответь на вопрос чем обосновывается при этом отказ от доказуемости кода?

    E>>Не жалко процедурного стиля программирования и слабейшего предусловия с ним?..

    J>э?
    Гугол? (я там выше сослался прямо на основополагающую работу)

    J>Очевидно, если ты предполагаешь такие гонки, надо программировать иначе

    В смысле "такие гонки"? Сейчас ОС многозадачные, ко многим реурсам есть доступ у многих пользователей со многих компов, к тому же...
    Банальный сценарий. Ты чего-то там делаешь, а в это время в фоне загудел бэкап или антивирь...
    Доступ к файлу -- это всегда гонки. Если твоя программа будет падать не каждый день, а каждую неделю, когда гонки таки случатся, то ты её просто вообще никогда не отладишь и всё.
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[30]: Вот еще, или я, кажется, читать разучился
    От: Patalog Россия  
    Дата: 27.02.13 07:17
    Оценка: 8 (2) +3
    Здравствуйте, alex_public, Вы писали:

    []

    _>Это в каждом конкретном случае надо смотреть.


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

    _>Например ваш пример с вызовами из jscript'a похоже как раз отлично подходящий для исключений.


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

    _>Но не хотите же вы сказать что у вас большинство проектов по такой схеме работают?


    Упаси бог. Это жуткий легаси, который я вынужден поддерживать вот уже 3-й год.
    Сейчас правда я его отрефакторил до такой степени, что это практически с 0 написанный код.
    Но нек. решения я вынужден поддерживать, в т.ч. проброс ошибок, ибо это публичный контракт и на это завязано куча решений 3-х лиц.

    P>>Да и вообще, народ который пользуется исключениями поголовно этим страдает. Вкупе с необычной формой мазохизма.

    P>>Только некоторые отдельные товарищи стоят в позе д'Артаньяна.

    _>Да, есть много народа, который применяет исключения везде, в том числе и где не надо. Видимо считают это чем-то типа серебряной пули...


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

    хъ

    _>Всё очень просто и я уже даже писал кому-то здесь об этом.

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

    Ясное дело просто. Конечно могу, средство (язык) позволяет, вы мне не начальник, с чего я у вас разрешение буду спрашивать?

    _>Но имеет смысл их применять только для случаев обработки где-то очень далеко по стеку вызовов,

    _>т.к. в противоположном случае они просто не приносят никаких бонусов (а код при этом усложняют) по сравнению с теми же кодами возврата.

    А вот это сильное утверждение, которое требует столь же сильной аргументации. Не томите уже.
    Вот к примеру — чем try\catch {} сложнее чем if(err) {}? Ничем. Зато если вы завтра отрефакторите код так, что ф-я уйдет с 1-го уровня вложенности дальше — вы вдруг не забудете написать лапшу типа if(err) return err и потерять ошибку, ибо это будет не нужно.
    И вообще, что значит "очень далеко по стеку вызовов"? Сколько вешать в граммах?
    А чем throw сложнее return? Тем что у пишущих return не принято думать о том, что возвращая ошибку нужно в той же мере заботиться об утечках и инвариантах что и в случае throw?
    Почетный кавалер ордена Совка.
    Re[37]: Немного офтопа...
    От: Erop Россия  
    Дата: 27.02.13 07:35
    Оценка:
    Здравствуйте, MTD, Вы писали:

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


    Если даже это и так, то зачем ты написал это вот своё собщение?..
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[31]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 27.02.13 07:49
    Оценка:
    Здравствуйте, Patalog, Вы писали:

    P>Вот к примеру — чем try\catch {} сложнее чем if(err) {}?


    Примерно тем же, чем goto сложнее чем if|while. Программа утрачивает процедурность...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[42]: Вот еще, или я, кажется, читать разучился
    От: jazzer Россия Skype: enerjazzer
    Дата: 27.02.13 09:15
    Оценка:
    Здравствуйте, Erop, Вы писали:

    T>> Т.е. ты видишь серьезные отличие между try catch и __try __except ?

    E>Конечно вижу. Обработчик SEH может вызвать terminate() ДО раскрутки стека

    Блин. Еще раз: открой для себя set_new_handler.

    Required behavior: A new_handler shall perform one of the following:
    — make more storage available for allocation and then return;
    — throw an exception of type bad_alloc or a class derived from bad_alloc;
    — terminate execution of the program without returning to the caller;

    Как видишь, нехватку памяти можно обрабатывать как ты хочешь (сохранение данных и вылет без раскрутки стека), в рамках стандартного С++, безо всяких SEH-ов.

    То же относится к set_terminate:

    Required behavior: A terminate_handler shall terminate execution of the program without returning to the caller.
    Default behavior: The implementation’s default terminate_handler calls abort().

    и set_unexpected:

    Required behavior: An unexpected_handler shall not return. See also 15.5.2.
    Default behavior: The implementation’s default unexpected_handler calls std::terminate().

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

    Важное отличие от at_exit — установку обработчика можно откатить, в то время как то, что зарегистрировано в atexit, никак уже не уберешь (разве что свою инфраструктуру городить для этого).
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[42]: Вот еще, или я, кажется, читать разучился
    От: Tanker  
    Дата: 27.02.13 09:35
    Оценка:
    Здравствуйте, Erop, Вы писали:

    T>>По твоему исключения SEH, как ты предложил, это сишный подход ?

    E>Я где-то предлагал SEH? Это ты про сегфолт что ли? Поверх SEH можно сделать обработку похожую на сигналы, но весь SEH для этого не нужен

    Конечно предполагал. Тебе еще надо допилить SEH до приемлемого юзания. Получится ровно то же, только на коленке.

    T>> Т.е. ты видишь серьезные отличие между try catch и __try __except ?

    E>Конечно вижу. Обработчик SEH может вызвать terminate() ДО раскрутки стека

    Принципиальной разницы нет, и то и другое это исключения.
    The animals went in two by two, hurrah, hurrah...
    Re[42]: Вот еще, или я, кажется, читать разучился
    От: Tanker  
    Дата: 27.02.13 09:36
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    T>>По твоему исключения SEH, как ты предложил, это сишный подход ? Т.е. ты видишь серьезные отличие между try catch и __try __except ? Я даже и не знаю, как быть.


    _>Нууу при определённых флагах в VC это вполне может быть одним и тем же. ))) А вообще __try __except — это всё же не C++. )))


    Разумеется, речь то про сишную обработку исключений.
    The animals went in two by two, hurrah, hurrah...
    Re[43]: Вот еще, или я, кажется, читать разучился
    От: jazzer Россия Skype: enerjazzer
    Дата: 27.02.13 10:15
    Оценка: 7 (1) +3
    Здравствуйте, Erop, Вы писали:

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

    Зачем рушить? Ведь есть же такой уровень, при котором программа может принять осмысленное решение, что делать в случае отсутствия файла?
    Рушить из-за отсутствия файла нужно только программы типа grep, т.е. работа которых бессмысленна целиком, если файла нет.

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

    E>И собственно он-то и представляет интерес, а не кидание какашками или измерения накладных расходов на SEH сам по себе...
    Тут я согласен, если под "расползается" ты имеешь в виду, что весь код должен быть устойчив к исключениям.
    И если в случае кодов ошибок это расползание видно явно и, как следствие №1, замусоривает код до невозможности, а как следствие №2, поощряет ленивых программеров забивать на обработку кодов, то в случае исключений код становится чистым и ясным, а игнорирование ошибки невозможно.

    J>>Коды ошибок оправданы только там, где обработка ошибок происходит постоянно на всех уровнях и является именно обработкой с несколькими ветками, а не просто пробрасыванием "if(err)return err;". Потому что такое пробрасывание — это просто закат солнца исключения вручную.

    E>Даже в этом случае это не тоже самое, потому, что при кодах "проброс" происходит в явном месте алгоритма...
    Ага. В каждой строчке (или еще хуже — в каждом подвыражении, которое теперь приходится разбивать на expression statement-ы и обвешивать замечательными "if(err)return err;"). Офигительная разница.

    J>>Ничего не понял, но отвечу на то, что понял: способность функции бросать исключения — это часть ее интерфейса, совершенно верно.

    E>Это очень сильно иная парадигма.
    Разве? Чем документирование кодов возврата отличается от документирования исключений?

    E>Это примерно как "goto в программе может быть, ну пара даже может, но только в тех местах, где без goto совсем-совсем сильно нехорошо" против "goto -- обычный оператор управления потоком исполнения"...

    E>Это очень разные подходы, с очень разными накладными расходами, скилами архитекторов. кодеров и тестировщиков и т. д...
    Не могу согласиться, сорри. return в середине функции эквивалентен goto на конец функции. Ты у нас сторонник подхода "Из функции должен быть ровно один return"? Если нет, то объясни мне, чем отличается исключение от множественного return.

    E>На мой взгляд объединять их в один глупо.

    Это странный вывод.

    J>>Интерфейс функции — это все, что она принимает, плюс все, что она выдает обратно. Очевидно, исключения (и коды возврата) во вторую часть входят.

    E>А как ты относишься к возможности передавать в функцию метки для перехода в каком-то особом случае? Или, например, нескольким входам в функции?
    E>От этого всего отказались под воздействием идей Дейкстры, изложенных им в "Дисциплине программирования". Переход к массовым исключениям означает фактическийотказ от процедурного программирования. Это осознанный шаг? Если да, то он чем аргументируется?..

    Ты, наверное, на ФУПМе учился Можешь закидать меня радиоактивными какашками, но я с этой идиомой не знаком. Сейчас прочитал в вики по диагонали и пришел к выводу, что эта радость не предусматривает return в середине функции — я прав?

    Во-вторых, просто из определения, если я его правильно понял, weakest precondition — это условия, при которых операция даст нужный результат.
    Так вот, weakest precondition для fopen с ненулевым результатом будет точно таким же, как для fopen, бросающей исключения в случае неудачи.
    Поправь, если не так.

    E>Банальный сценарий. Ты чего-то там делаешь, а в это время в фоне загудел бэкап или антивирь...

    E>Доступ к файлу -- это всегда гонки. Если твоя программа будет падать не каждый день, а каждую неделю, когда гонки таки случатся, то ты её просто вообще никогда не отладишь и всё.
    Ну, например, вместо file_exists будет lock_file_if_exists
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[44]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 27.02.13 12:32
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>Зачем рушить? Ведь есть же такой уровень, при котором программа может принять осмысленное решение, что делать в случае отсутствия файла?

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

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

    Да, точно так.

    J>И если в случае кодов ошибок это расползание видно явно и, как следствие №1, замусоривает код до невозможности, а как следствие №2, поощряет ленивых программеров забивать на обработку кодов, то в случае исключений код становится чистым и ясным, а игнорирование ошибки невозможно.


    IMHO, всё ровно наоборот.
    1) Подумали ли о том, что будет, если провалится то или это мето или просто так взяли и написали "чисто и ясно" и расслабились, НЕ ВИДНО.
    2) Провал чего-то может быть очень сложным, рекурсивным и вообще маорпонимабельным.
    3) Поведение описано в программе неявно, неверефицируемо, нетестируемо и труднопонимаемо...

    J>Ага. В каждой строчке (или еще хуже — в каждом подвыражении, которое теперь приходится разбивать на expression statement-ы и обвешивать замечательными "if(err)return err;"). Офигительная разница.

    Зачем это делать в каждом подвыражении?..

    J>Разве? Чем документирование кодов возврата отличается от документирования исключений?

    Тем, что исключение для объемлющего кода выглядит как goto. поток управления в ВЫЗВАЮЩЕМ коде становится непроцедурным...

    J>Не могу согласиться, сорри. return в середине функции эквивалентен goto на конец функции. Ты у нас сторонник подхода "Из функции должен быть ровно один return"? Если нет, то объясни мне, чем отличается исключение от множественного return.

    Читай Дейкстру.
    Я не противник goto, кстати, и не противник множественного return
    Я противник кода, который можно интерпретировать, как набор операций последовательно переводящих программу из одного состояния в другое.
    То есть, если процедурность не страдает, то в goto нет проблемы (например выход из вложенного цикла по goto не проблема), а если страдает, то всё плохо и без goto

    J>Ты, наверное, на ФУПМе учился

    Нет, на проблемах. Но какое это имеет отношение к теме?

    J>Можешь закидать меня радиоактивными какашками, но я с этой идиомой не знаком.

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

    J>Сейчас прочитал в вики по диагонали и пришел к выводу, что эта радость не предусматривает return в середине функции — я прав?

    В математически чистом варианте да, вернее для каждого return надо будет отдельно доказать попадание в постусловие. На практике бывает много кода, который очевидно не трудно доказуем таким образом. Даже если return'ов много...

    J>Во-вторых, просто из определения, если я его правильно понял, weakest precondition — это условия, при которых операция даст нужный результат.

    Это слабейшее предусловие заданного постусловия.
    J>Так вот, weakest precondition для fopen с ненулевым результатом будет точно таким же, как для fopen, бросающей исключения в случае неудачи.
    J>Поправь, если не так.
    Да так. Дальше у нас возникает вопрос, допускает ли предусловие программы неоткрывающиеся файлы. Если таки да, то вариант с исключениями не канает, потому, что в некоторых допустимых предусловиями состояниях в результате выполнения попадём в состояние где выполненность постусловия неопределена...

    J>Ну, например, вместо file_exists будет lock_file_if_exists

    И чем это будет отличатьcя от обычного fopen?..
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[43]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 27.02.13 12:43
    Оценка:
    Здравствуйте, Tanker, Вы писали:

    T>Принципиальной разницы нет, и то и другое это исключения.


    Тебе кажется, что возможность не разматывать стек непринципиальна?
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[43]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 27.02.13 12:46
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>Как видишь, нехватку памяти можно обрабатывать как ты хочешь (сохранение данных и вылет без раскрутки стека), в рамках стандартного С++, безо всяких SEH-ов.

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

    Но и сегфолт тоже стоит обрабатывать, если есть критические данные и ресурсы...
    можно и всё разом тогда.

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

    Конечно везде, вернее везде, кроме throw...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[40]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 27.02.13 14:32
    Оценка: -1
    Здравствуйте, jazzer, Вы писали:

    J>Код "прямой и модульной изначальной архитектуры" на кодах возврата на в студию. С обоснованием прямизны и модульности.

    J>И не забывай, мы тут говорим об обработке ошибок, так что потрудись убедить нас, что ни одной ошибки случайно не пропущено и что обрабатывать ошибки кодами возврата на порядок удобнее и безопаснее, чем исключениями.
    J>Просим! Просим!

    Я нигде не говорил, что обрабатывать ошибки кодами возврата на порядок удобнее и безопаснее, чем исключениями. Надо читать собеседников внимательнее. Мой тезис был в том, что в большинстве практических случаев (однако естественно что ситуации оптимальные для исключений всё же есть) замена кодов возврата на исключения не приносит вообще никакой пользы. Вреда правда тоже особого нет, разве что небольшое увеличение объёма кода. Но если нет пользы, то и нет смысла.
    Re[41]: Вот еще, или я, кажется, читать разучился
    От: Vzhyk  
    Дата: 27.02.13 14:35
    Оценка: +1
    On 27.02.2013 17:32, alex_public wrote:

    > Мой тезис был в том, что в большинстве практических

    > случаев (однако естественно что ситуации оптимальные для исключений всё
    > же есть) замена кодов возврата на исключения не приносит вообще никакой
    > пользы.
    Чево? Если код возврата — суть ошибка, то логично он должен быть заменен
    на исключение (для С++), если это результат работы функции, то, конечно,
    нет.
    Posted via RSDN NNTP Server 2.1 beta
    Re[31]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 27.02.13 15:05
    Оценка: -1
    Здравствуйте, Patalog, Вы писали:

    _>>Да, есть много народа, который применяет исключения везде, в том числе и где не надо. Видимо считают это чем-то типа серебряной пули...

    P>Т.е. позу Вы сменить не хотите. Понятно.

    Так я же это не конкретно про вас, а вообще... )

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


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

    P>А вот это сильное утверждение, которое требует столь же сильной аргументации. Не томите уже.

    P>Вот к примеру — чем try\catch {} сложнее чем if(err) {}? Ничем.

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

    P>Зато если вы завтра отрефакторите код так, что ф-я уйдет с 1-го уровня вложенности дальше — вы вдруг не забудете написать лапшу типа if(err) return err и потерять ошибку, ибо это будет не нужно.


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

    P>И вообще, что значит "очень далеко по стеку вызовов"? Сколько вешать в граммах?


    Ну я же говорил что это в какой-то степени дело личного вкуса. Которым мы тут сейчас и делимся.

    P>А чем throw сложнее return? Тем что у пишущих return не принято думать о том, что возвращая ошибку нужно в той же мере заботиться об утечках и инвариантах что и в случае throw?


    Если человек пишет в идиоме RAII, то ему в принципе должно быть безразлично. Но вы опять же пытаетесь показать что исключения не хуже кодов возврата. Так с этим никто и не спорит. Но они должны быть не просто не хуже, а заметно лучше, что бы появлялся смысл их применения.
    Re[42]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 27.02.13 15:07
    Оценка:
    Здравствуйте, Vzhyk, Вы писали:

    V>Чево? Если код возврата — суть ошибка, то логично он должен быть заменен

    V>на исключение (для С++), если это результат работы функции, то, конечно,
    V>нет.

    Приведи, пожалуйста, 10 примеров пар функция + код возврата, который точно ошибка...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[43]: Вот еще, или я, кажется, читать разучился
    От: Vzhyk  
    Дата: 27.02.13 15:12
    Оценка: +1
    On 27.02.2013 18:07, Erop wrote:

    > Приведи, пожалуйста, 10 примеров пар функция + код возврата, который

    > точно ошибка...
    Это уже даже не смешно становиться. Самим еще не надоело обсуждать
    сферических коней в вакууме. Понятие "ошибка" может быть только в
    контексте твоей программы, а не вообще. В каких-то ситуация невыделения
    памяти не ошибка, а вполне себе рабочая ситуация, которую надо
    программно решить, в других нужно закончить программу с сообщением, что
    память не выделилась и т.д.
    Posted via RSDN NNTP Server 2.1 beta
    Re[42]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 27.02.13 15:22
    Оценка: +1
    Здравствуйте, Vzhyk, Вы писали:

    V>Чево? Если код возврата — суть ошибка, то логично он должен быть заменен

    V>на исключение (для С++), если это результат работы функции, то, конечно,
    V>нет.

    Ну мы тут уже выяснили что все подобные фразы сводятся к вопросу "а что считать ошибкой"... Но в любом случае в ответ на вашу фразу сразу возникает банальный вопрос "а зачем?". Не для галочки же просто, а должны быть какие-то преимущества от такой замены...
    Re[43]: Вот еще, или я, кажется, читать разучился
    От: Vzhyk  
    Дата: 27.02.13 15:24
    Оценка:
    On 27.02.2013 18:22, alex_public wrote:

    > Но в любом случае в ответ на вашу фразу сразу

    > возникает банальный вопрос "а зачем?". Не для галочки же просто, а
    > должны быть какие-то преимущества от такой замены...
    Ну, например, потому, что код становится лаконичнее, чище, читать его проще.
    Posted via RSDN NNTP Server 2.1 beta
    Re[44]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 27.02.13 15:35
    Оценка:
    Здравствуйте, Vzhyk, Вы писали:

    >> Приведи, пожалуйста, 10 примеров пар функция + код возврата, который

    >> точно ошибка...
    V>Это уже даже не смешно становиться. Самим еще не надоело обсуждать
    V>сферических коней в вакууме.

    поэтому и прошу привести десять КОНКРЕТНЫХ примеров того, что ТЫ САМ считаешь "ошибкой"...

    А то тут какой-то грандиозный разброс мнений по этому поводу продемонстрирован, что делает обсуждение совершенно неконкретным...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[45]: Вот еще, или я, кажется, читать разучился
    От: Vzhyk  
    Дата: 27.02.13 15:40
    Оценка:
    On 27.02.2013 18:35, Erop wrote:

    > поэтому и прошу привести десять КОНКРЕТНЫХ примеров того, что ТЫ САМ

    > считаешь "ошибкой"...
    Например отсутсвие файла, где данные для рассчетов лежат. Невозможность
    выделить нужный мне объем памяти в конкретной задаче (например, проще
    закрыть несколько других и запустить заново прогу или вообще перегрузить
    комп).
    Posted via RSDN NNTP Server 2.1 beta
    Re[44]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 27.02.13 15:50
    Оценка: -1
    Здравствуйте, Vzhyk, Вы писали:

    V>Ну, например, потому, что код становится лаконичнее, чище, читать его проще.


    Это звучит правильно только для случаев отката куда-то очень далеко назад по стеку вызовов при обработке ошибок.
    Re[45]: Вот еще, или я, кажется, читать разучился
    От: Vzhyk  
    Дата: 27.02.13 15:56
    Оценка:
    On 27.02.2013 18:50, alex_public wrote:

    > Это звучит правильно только для случаев отката куда-то очень далеко

    > назад по стеку вызовов при обработке ошибок.
    Неа. Код ты пишешь в первую очередь для людей, тех кто его потом читать
    будет, поддерживать (в том числе и для себя), компилятору же пофиг,
    абсолютно.
    Дальше, если в твоем коде так называемая "ошибка" представляет собой
    типичное поведение программы, то нафига исключение, а то таким макаром и
    if a<b можно через исключение написать.
    Posted via RSDN NNTP Server 2.1 beta
    Re[32]: Вот еще, или я, кажется, читать разучился
    От: Patalog Россия  
    Дата: 27.02.13 16:11
    Оценка: 1 (1) +1
    Здравствуйте, alex_public, Вы писали:

    хъ

    P>>А вот это сильное утверждение, которое требует столь же сильной аргументации. Не томите уже.

    P>>Вот к примеру — чем try\catch {} сложнее чем if(err) {}? Ничем.

    _>Банально размером кода. И не забываем про необходимость объявления классов исключений (если мы хотим делать всё совсем красиво) и т.п... Т.е. в случаях типа моего примера имеем определённый объём работы ради нулевой пользы.


    Необходимость в новых классах исключений сильно преувеличена. Мне на практике хватает готовых из стандартной библиотки и буста.
    Кроме того, в случе кодов возврата точно так же нужно городить новые enum'ы для кодов возврата.

    P>>Зато если вы завтра отрефакторите код так, что ф-я уйдет с 1-го уровня вложенности дальше — вы вдруг не забудете написать лапшу типа if(err) return err и потерять ошибку, ибо это будет не нужно.


    _>Дело в том, что при нормальной архитектуре уход на другой уровень должен будет означать смену контекста/значения ошибки.

    _>Т.е. в любом случае надо делать не проброс ошибки, а какое-то переформатирование под новые смыслы.

    Ничем не отличается от исключений, кроме то, что в случае исключений мы можем на это забить, так как уровнем выше мы словим исключение по базе, а в твоем случае мы вынуждены пробрасывать\переформатировать, иначе потеряем ошибку и останемся в невалидном состоянии.
    А при смене значения ошибки мы наблюдаем удивительный цирк переливания из пустого в порожнее — перекладывание из одного enum'а в другой, зачастую огороженный макросом со switch внутри.

    хъ

    P>>А чем throw сложнее return? Тем что у пишущих return не принято думать о том, что возвращая ошибку нужно в той же мере заботиться об утечках и инвариантах что и в случае throw?


    _>Если человек пишет в идиоме RAII, то ему в принципе должно быть безразлично. Но вы опять же пытаетесь показать что исключения не хуже кодов возврата. Так с этим никто и не спорит. Но они должны быть не просто не хуже, а заметно лучше, что бы появлялся смысл их применения.


    На мой вкус — кода заметно меньше, код прозрачнее, по happy path уж точно, что не маловажно для чтения оного через N времени.
    А то иногда бывает так, что за обработкой ошибок не видно основной логики.

    ЗЫ В библиотеках я по возможности предоставляю два вида интерфейса — с исключениями и с кодом ошибки, как это сделано в boost.asio
    Почетный кавалер ордена Совка.
    Re[46]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 27.02.13 17:17
    Оценка:
    Здравствуйте, Vzhyk, Вы писали:

    V>Например отсутсвие файла, где данные для рассчетов лежат. Невозможность

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

    То есть "ошибка" -- это то, после чего программу надо аварийно отгружать? Я верно понял или нет?
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[47]: Вот еще, или я, кажется, читать разучился
    От: Vzhyk  
    Дата: 27.02.13 18:06
    Оценка:
    On 27.02.2013 20:17, Erop wrote:

    > То есть "ошибка" -- это то, после чего программу надо аварийно

    > отгружать? Я верно понял или нет?
    В общем-то так. Все остальное — не ошибка, а требование.
    Posted via RSDN NNTP Server 2.1 beta
    Re[33]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 27.02.13 18:44
    Оценка: +1
    Здравствуйте, Patalog, Вы писали:

    P>Необходимость в новых классах исключений сильно преувеличена. Мне на практике хватает готовых из стандартной библиотки и буста.

    P>Кроме того, в случе кодов возврата точно так же нужно городить новые enum'ы для кодов возврата.

    Ага, я тоже стандартные предпочитаю использовать. А в случае кодов возврата опять же предпочитаю сводить логику к true/false...

    P>Ничем не отличается от исключений, кроме то, что в случае исключений мы можем на это забить, так как уровнем выше мы словим исключение по базе, а в твоем случае мы вынуждены пробрасывать\переформатировать, иначе потеряем ошибку и останемся в невалидном состоянии.


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

    P>На мой вкус — кода заметно меньше, код прозрачнее, по happy path уж точно, что не маловажно для чтения оного через N времени.

    P>А то иногда бывает так, что за обработкой ошибок не видно основной логики.

    Вот разделение логики и ошибок на уровне разных ключевых слов — это пожалуй единственный плюс, который можно приписать исключениям. Но он далеко не всем по вкусу. )
    Re[48]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 27.02.13 18:46
    Оценка: +1
    Здравствуйте, Vzhyk, Вы писали:

    >> То есть "ошибка" -- это то, после чего программу надо аварийно отгружать? Я верно понял или нет?

    V>В общем-то так. Все остальное — не ошибка, а требование.

    Хыхы, при таком определение ошибки я тоже готов написать что все ошибки надо обрабатывать только с помощью исключений.
    Re[49]: Вот еще, или я, кажется, читать разучился
    От: Vzhyk  
    Дата: 27.02.13 18:50
    Оценка:
    On 27.02.2013 21:46, alex_public wrote:

    > Хыхы, при таком определение ошибки я тоже готов написать что все ошибки

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

    Если у вас в требованиях есть обработка неких ситуаций, то причем тут
    исключения, если нет, то вывались корректно и все, сообщив о причине —
    здесь исключения самое то.
    Posted via RSDN NNTP Server 2.1 beta
    Re[46]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 27.02.13 19:02
    Оценка: 3 (1)
    Здравствуйте, Vzhyk, Вы писали:

    V>Неа. Код ты пишешь в первую очередь для людей, тех кто его потом читать

    V>будет, поддерживать (в том числе и для себя), компилятору же пофиг,
    V>абсолютно.
    Ну так поинт состоит в том, что коды возрата ПОНЯТНЕЕ, потому, что они ЛОКАЛЬНЕЕ.
    Не надо смотреть в 100500 мест, где что могло случиться или не случиться, где могли чего-то обеспечить или не смогли, ну есть у тебя пять вызвавших друг друга функций. Просто читаешь их код и всё. Ошибка содержится ровно в этих 100 строках, а не "где-то ещё"...

    V>Дальше, если в твоем коде так называемая "ошибка" представляет собой

    V>типичное поведение программы, то нафига исключение, а то таким макаром и
    V>if a<b можно через исключение написать.

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

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

    на самом деле моя проблема мне стала после этой дискуссии понятна лучше.
    Я понял, что в коде без исключений есть некоторая мат. модель кода, которая позволяет мне с ним работать достаточно продуктивно и хорошо. Писать assert's, проверять пред и пост условия, инварианты циклов и т. д.
    Это таки то, что описано у Дейкстры в "Дисциплине программирования" и у его последователей.
    Традиционно такой подход к организации императивного кода получил название "процедурное программирование".
    Для функциональщины тоже есть подходящий мат. аппарат. А вот для "кода с исключениями" я такого аппарата не знаю.
    Может его кто-то таки придумал, просто я не в курсе? Это легко может такое быть. И тогда бы, если бы такой аппарат был, многие вопросы, где там стоит или не стоит пихать исключения, скорее всего можно было бы формально задать и получить на них формальный ответ, а так рассусол и кустарзина с вкусовщиной сплошные выходят...


    Слушайте, люди добрые, а правда, есть мат аппарат для анализа кода с иключениями?
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[33]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 27.02.13 19:06
    Оценка:
    Здравствуйте, Patalog, Вы писали:

    P>Ничем не отличается от исключений, кроме то, что в случае исключений мы можем на это забить, так как уровнем выше мы словим исключение по базе, а в твоем случае мы вынуждены пробрасывать\переформатировать, иначе потеряем ошибку и останемся в невалидном состоянии.


    Дык то, что при рефакторинге мы можем на чать оного забить и понадеяться, что оно само как-нибудь -- это скорее минус, чем плюс жеж?
    так как если оно само не сможет даже всего раз из 10, то в те места прийдётся вникать ДВАЖДЫ...
    И хорошо, если оба раза ДО релиза...

    P>На мой вкус — кода заметно меньше, код прозрачнее, по happy path уж точно, что не маловажно для чтения оного через N времени.

    P>А то иногда бывает так, что за обработкой ошибок не видно основной логики.

    Ну так тоже не надо писать. На исключениях говнокод породить ещё проще, чем на кодах возврата... И при том и при другом подходе есть удачные и не особо удачные реализации. А самые удачные обычно совмещают ОБА подхода. Что-то через исключения, а что-то через коды...

    P>ЗЫ В библиотеках я по возможности предоставляю два вида интерфейса — с исключениями и с кодом ошибки, как это сделано в boost.asio

    Ну для библиотек это часто хороший выбор. +100500
    Особенно, если не понятно каких тактик обработки ошибок придерживаются пользователи.
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[48]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 27.02.13 19:08
    Оценка:
    Здравствуйте, Vzhyk, Вы писали:

    >> То есть "ошибка" -- это то, после чего программу надо аварийно

    >> отгружать? Я верно понял или нет?
    V>В общем-то так. Все остальное — не ошибка, а требование.

    Дык если ты тоже придерживаешься позиции, что исключения надо кидать только тогда, когда случилось что-то такое, что программу налдо отгрузить, то у нас с тобой очень схожие позиции по этому вопросу.
    Только я считаю, что раз мы всё равно аварийно отгружаемся, то нам ещё и валидность нафиг не упёрлась и утечки не критичны. Достаточно того, что бы то, что не утекло смогло разрушиться без фейерверков...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[47]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Vzhyk  
    Дата: 27.02.13 19:18
    Оценка: 4 (1) +1
    On 27.02.2013 22:02, Erop wrote:

    > Ну так поинт состоит в том, что коды возрата ПОНЯТНЕЕ, потому, что они

    > ЛОКАЛЬНЕЕ.
    А код легче читать не потому, что он локальнее, а потому, что он
    лаконичнее. Впрочем, как и книги. Пример Лев Толстой, которого читать
    вообще практически невозможно, зато все его отступления локальны.
    Правило простое, если можно что-то не писать — не пиши.
    Второе, код функции больше страницы человеком вопринимается очень плохо,
    а проверки кодов возврата его раздуют так или иначе. Если ты навернешь
    на дэфайнах, код станет еще сложнее читать, ибо хер знаешь, во что там
    твои дэфайны развернуться (но иногда это нормально выглядит).

    > Да, это очень хороший и правильный тезис и я его абсолютно разделяю.

    > Дальше у нас возникает такая беда, что в нижележащей функции мы не
    > знаем, это штатная ситуация или таки ошибка, которая уже достойна
    > исключений.
    Знаем, потому как есть требования. Если их нет, их надо сформировать.

    > А на вызывающей стороне, там где мы уже знаем, ошибка это или штатная

    > ситуация, мы обычно уже можем эту ошибку обработать, по крайней мере
    > начать обрабатывать...
    > и тогда возникает вопрос, а зачем нам тут уже исключения, если мы и так
    > можем начать обрабатывать?..
    И так мы зацикливаемся. А это нам надо? Нет.

    > Традиционно такой подход к организации императивного кода получил

    > название "процедурное программирование".
    > Для функциональщины тоже есть подходящий мат. аппарат. А вот для "кода с
    > исключениями" я такого аппарата не знаю.
    Я бы так не утверждал. Но если его нет и он нужен, придумают те, кто
    занимается теорией программирования. Мы здесь все больше практики и
    теорией программирования не занимаемся (если тебе это интерсно, то
    понятно ответ надо искать не на этом форуме).
    Исключения удобны и выгодны. Неужели отсутсвие математической модели в
    данный момент должно нам запрещать использовать некое явление?

    > Может его кто-то таки придумал, просто я не в курсе? Это легко может

    > такое быть. И тогда бы, если бы такой аппарат был, многие вопросы, где
    > там стоит или не стоит пихать исключения, скорее всего можно было бы
    > формально задать и получить на них формальный ответ, а так рассусол и
    > кустарзина с вкусовщиной сплошные выходят...
    Ну что тебе сказать. Поднимаешь несколько десятков статей по теории
    программирования, ищешь ответ, а потом нам здесь рассказываешь.
    Posted via RSDN NNTP Server 2.1 beta
    Re[49]: Вот еще, или я, кажется, читать разучился
    От: Vzhyk  
    Дата: 27.02.13 19:28
    Оценка:
    On 27.02.2013 22:08, Erop wrote:

    > Только я считаю, что раз мы всё равно аварийно отгружаемся, то нам ещё и

    > валидность нафиг не упёрлась и утечки не критичны. Достаточно того, что
    > бы то, что не утекло смогло разрушиться без фейерверков...
    Конечно.
    Я не понимаю, зачем вы здесь, хором надували муху до размеров слона.
    У нас есть всегда некие требования к любому модулю (части) программы и
    мы именно их и должны удовлетворить (ну или расширить требования по мере
    разработки). Все что выходит за требования — корректно умираем.
    Но не забываем о том, что программу мы пишем для людей и посему должны
    быть маскимально лаконичны и понятны читателю.
    И еще момент, не забываем, что исключения происходят в редких ситуациях,
    а коды возврата нужно проверять, а это может плохо сказаться на скорости
    работы программы.
    Posted via RSDN NNTP Server 2.1 beta
    Re[48]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 27.02.13 19:29
    Оценка:
    Здравствуйте, Vzhyk, Вы писали:

    >> Для функциональщины тоже есть подходящий мат. аппарат. А вот для "кода с

    >> исключениями" я такого аппарата не знаю.
    V>Я бы так не утверждал. Но если его нет и он нужен, придумают те, кто
    V>занимается теорией программирования. Мы здесь все больше практики и
    V>теорией программирования не занимаемся (если тебе это интерсно, то
    V>понятно ответ надо искать не на этом форуме).
    В смысле "не утверждал"? Ты думаешь, что я таки знаю, но скрываю?
    Его вроде как и правда нет. Потому-то код с частыми исключениями так похож на goto-спагети...

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


    V>Исключения удобны и выгодны. Неужели отсутсвие математической модели в

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


    V>Ну что тебе сказать. Поднимаешь несколько десятков статей по теории

    V>программирования, ищешь ответ, а потом нам здесь рассказываешь.

    Я как-то искал и не нашёл...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[49]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Vzhyk  
    Дата: 27.02.13 19:42
    Оценка:
    On 27.02.2013 22:29, Erop wrote:

    > В смысле "не утверждал"? Ты думаешь, что я таки знаю, но скрываю?

    Нет. Если ты не знаешь, то это не говорит, что его нет.

    > Пока что понятно только одно -- базовая и

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

    > А что значит "выгодны"? В чём выгода измеряется? отсутсвие модели мешает

    > выработать оптимальную стратегию использования, например...
    Если тебе нужна оптимальная стратегия, то садишьс яи разрабатываешь
    модель. В любом случае, если явление есть, то и модель строится.
    Моя же выгода чисто утилитарная — время написания программы и
    соответсвенно стоимость.

    > Я как-то искал и не нашёл...

    Ну я тебе еще могу подкинуть темку по которой ты будешь искать и многого
    не найдешь, не будучи докой в этой теме. Сейчас практически в любой
    научной дисциплине сначала нужно достигнуть некоторого уровня знаний,
    чтобы найти что-то посерьезнее научно-популярных изложений.
    Posted via RSDN NNTP Server 2.1 beta
    Re[41]: Вот еще, или я, кажется, читать разучился
    От: jazzer Россия Skype: enerjazzer
    Дата: 28.02.13 00:42
    Оценка: 8 (1) +4
    Здравствуйте, alex_public, Вы писали:

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


    J>>Код "прямой и модульной изначальной архитектуры" на кодах возврата на в студию. С обоснованием прямизны и модульности.

    J>>И не забывай, мы тут говорим об обработке ошибок, так что потрудись убедить нас, что ни одной ошибки случайно не пропущено и что обрабатывать ошибки кодами возврата на порядок удобнее и безопаснее, чем исключениями.
    J>>Просим! Просим!

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

    Супер. Так если кодами ошибок не удобнее и не безопаснее, зачем обрабатывать ошибки ими?
    И что там насчет "прямой и модульной изначальной архитектуры" на кодах возврата? Или у тебя, кроме необоснованных заявлений, ничего нет?

    _>Мой тезис был в том, что в большинстве практических случаев (однако естественно что ситуации оптимальные для исключений всё же есть) замена кодов возврата на исключения не приносит вообще никакой пользы.


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

    _>Вреда правда тоже особого нет, разве что небольшое увеличение объёма кода.

    Небольшое — это в два раза за счет "if(err)return err;" после каждой строчки
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[45]: Вот еще, или я, кажется, читать разучился
    От: jazzer Россия Skype: enerjazzer
    Дата: 28.02.13 01:05
    Оценка: 7 (1) +1
    Здравствуйте, Erop, Вы писали:

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


    J>>Зачем рушить? Ведь есть же такой уровень, при котором программа может принять осмысленное решение, что делать в случае отсутствия файла?

    E>Чтобы можно было позволить себе не рушить, надо обеспечивать высокий уровень гарантий безопасности при исключениях, а это и есть то, что удорожает использование исключений...
    А этот уровень разве не нужен при использовании кодов возврата?

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

    E>Да, точно так.

    J>>И если в случае кодов ошибок это расползание видно явно и, как следствие №1, замусоривает код до невозможности, а как следствие №2, поощряет ленивых программеров забивать на обработку кодов, то в случае исключений код становится чистым и ясным, а игнорирование ошибки невозможно.


    E>IMHO, всё ровно наоборот.

    E>1) Подумали ли о том, что будет, если провалится то или это мето или просто так взяли и написали "чисто и ясно" и расслабились, НЕ ВИДНО.
    Аналогично не видно, обработали ли код возврата или это просто функция возвращает void, или если обработали, то все ли возможные значения обработаны.
    E>2) Провал чего-то может быть очень сложным, рекурсивным и вообще маорпонимабельным.
    И что? Он будет точно таким же и с кодами возврата. И действия по восстановлению работоспособности программы будут точно такими же.
    E>3) Поведение описано в программе неявно, неверефицируемо, нетестируемо и труднопонимаемо...
    Как в таком случае насчет RAII и деструкторов? Они тоже зовутся в программе неявно
    Насчет нетестируемости — так трудно вызвать исключение?
    Насчет труднопонимаемости — вообще не аргумент, имхо. Мне вот гораздо труднее установить корректность кода на кодах возврата.

    J>>Ага. В каждой строчке (или еще хуже — в каждом подвыражении, которое теперь приходится разбивать на expression statement-ы и обвешивать замечательными "if(err)return err;"). Офигительная разница.

    E>Зачем это делать в каждом подвыражении?..
    Потому что каждое подвыражение может обломаться. С исключениями мы можем об этом не беспокоиться, а с кодами возврата придется выражения разбить на подвыражения и проверять код возврата каждого.

    J>>Разве? Чем документирование кодов возврата отличается от документирования исключений?

    E>Тем, что исключение для объемлющего кода выглядит как goto. поток управления в ВЫЗВАЮЩЕМ коде становится непроцедурным...
    как return, а не как goto. Разницу видишь?

    J>>Не могу согласиться, сорри. return в середине функции эквивалентен goto на конец функции. Ты у нас сторонник подхода "Из функции должен быть ровно один return"? Если нет, то объясни мне, чем отличается исключение от множественного return.

    E>Читай Дейкстру.
    E>Я не противник goto, кстати, и не противник множественного return
    E>Я противник кода, который можно интерпретировать, как набор операций последовательно переводящих программу из одного состояния в другое.
    E>То есть, если процедурность не страдает, то в goto нет проблемы (например выход из вложенного цикла по goto не проблема), а если страдает, то всё плохо и без goto
    Замечательно. А теперь вспомним, что исключение — это по сути return, против которого ты ничего не имеешь.

    J>>Ты, наверное, на ФУПМе учился

    E>Нет, на проблемах. Но какое это имеет отношение к теме?
    Ну фупмов теорией грузят в большом количестве.

    J>>Можешь закидать меня радиоактивными какашками, но я с этой идиомой не знаком.

    E>Крайне настоятельно тогда рекоммендую...
    E>Там с азов всё идёт, так что можешь знакомые главы тупо пролистывать, но книжка очень дельная, и программисту её,в ернее изложенные в неё идеи, знать стоит. Есть по-русски и по-японски, ну и английский вариант тоже есть, есен пень
    спасибо, будет время — почитаю

    J>>Сейчас прочитал в вики по диагонали и пришел к выводу, что эта радость не предусматривает return в середине функции — я прав?

    E>В математически чистом варианте да, вернее для каждого return надо будет отдельно доказать попадание в постусловие. На практике бывает много кода, который очевидно не трудно доказуем таким образом. Даже если return'ов много...
    Ну так код на исключениях элементарно переписывается на таковой на return'ах

    J>>Во-вторых, просто из определения, если я его правильно понял, weakest precondition — это условия, при которых операция даст нужный результат.

    E>Это слабейшее предусловие заданного постусловия.
    ОК, минимальные условия, при которых операция даст нужный результат.

    J>>Так вот, weakest precondition для fopen с ненулевым результатом будет точно таким же, как для fopen, бросающей исключения в случае неудачи.

    J>>Поправь, если не так.
    E>Да так. Дальше у нас возникает вопрос, допускает ли предусловие программы неоткрывающиеся файлы. Если таки да, то вариант с исключениями не канает, потому, что в некоторых допустимых предусловиями состояниях в результате выполнения попадём в состояние где выполненность постусловия неопределена...
    Сорри, а почему тут предусловие программы (т.е. одно на всю программу), а не конкретного вызова? Очевидно, одни файлы критичны, а на другие можно и забить
    Так что у каждого вызова fopen свое постусловие, и соответственно свое соответствующее предусловие.
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[47]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: jazzer Россия Skype: enerjazzer
    Дата: 28.02.13 01:31
    Оценка: +2 :)
    Здравствуйте, Erop, Вы писали:

    E>на самом деле моя проблема мне стала после этой дискуссии понятна лучше.

    E>Я понял, что в коде без исключений есть некоторая мат. модель кода, которая позволяет мне с ним работать достаточно продуктивно и хорошо. Писать assert's, проверять пред и пост условия, инварианты циклов и т. д.
    E>Это таки то, что описано у Дейкстры в "Дисциплине программирования" и у его последователей.
    E>Традиционно такой подход к организации императивного кода получил название "процедурное программирование".
    E>Для функциональщины тоже есть подходящий мат. аппарат. А вот для "кода с исключениями" я такого аппарата не знаю.
    E>Может его кто-то таки придумал, просто я не в курсе? Это легко может такое быть. И тогда бы, если бы такой аппарат был, многие вопросы, где там стоит или не стоит пихать исключения, скорее всего можно было бы формально задать и получить на них формальный ответ, а так рассусол и кустарзина с вкусовщиной сплошные выходят...

    E>Слушайте, люди добрые, а правда, есть мат аппарат для анализа кода с иключениями?


    Мой формальный ответ такой: код на исключениях элементарно переписывается один-в-один на код с кодами возврата и return'ами, для которого все давно доказано (то, что множественные return'ы переписываются в гроздь if'ов, надеюсь, специально доказывать не надо?)

    Концептуально исключения — это просто сахар для кодов возврата (а errno будет еще более близкой аналогией).
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[50]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 28.02.13 02:36
    Оценка: +1
    Здравствуйте, Vzhyk, Вы писали:

    V>А не надо искать кошку там, где ее нет.


    V>Если у вас в требованиях есть обработка неких ситуаций, то причем тут

    V>исключения, если нет, то вывались корректно и все, сообщив о причине —
    V>здесь исключения самое то.

    Фокус в том, что если вы внимательно почитаете эту темку, то увидите что довольно много народа придерживается совсем другой позиции. А именно, что исключения надо использовать гораздо шире, чем описали вы. Вот с ними лично я тут и спорю понемногу. )))
    Re[42]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 28.02.13 02:53
    Оценка: +1 -1
    Здравствуйте, jazzer, Вы писали:

    J>Супер. Так если кодами ошибок не удобнее и не безопаснее, зачем обрабатывать ошибки ими?


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

    J>И что там насчет "прямой и модульной изначальной архитектуры" на кодах возврата? Или у тебя, кроме необоснованных заявлений, ничего нет?


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

    J>Главное отличие исключений от кодов возврата в том, что коды возврата по умолчанию игнорируются, а исключения — наоборот.

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

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

    _>>Вреда правда тоже особого нет, разве что небольшое увеличение объёма кода.

    J>Небольшое — это в два раза за счет "if(err)return err;" после каждой строчки

    Вообще то речь шла о том, что исключения дают небольшое увеличение объёма кода...
    Re: Tizen 2.0
    От: SkyDance Земля  
    Дата: 28.02.13 04:07
    Оценка:
    E>Будущее мобильной разработки, Tizen 2.0. По моему, шикарно... 6 new, 3 каста, 1 delete и даже E_SUCCESS

    Помнится, я в одном из форумов объяснял epic fail Symbian'а и тотальный уход в пользу iOS/Android именно подобным кодом и подходом к программированию вообще. Некоторые были не согласны, и превозносили Symbian как прекрасную ОС, якобы предательски убитую г-ном Элопом (и уже под это дело вагон теорий заговора).

    Теперь о том, откуда ноги растут у этого безобразия. "Вы не поверите" (С), но — из Intel. А туда, в свою очередь, попало после "перекрёстного опыления" Intel'овского поделия Moblin кодом из Maemo (кстати, в результате тяжелых родов получилось Meego, опять же, ожидаемо провалившаяся в силу тех же причин — "удобства" разработчиков портировать софт на этот вариант линукса).

    А потом все было щедро сдобрено корейским подходом, ведь изначально Tizen — это проект LiMo. По сути, аналог Android, даже в одно время "зачинались", просто LiMo гуглу продаться никак не могли. Собственно, когда Intel инвестировал в LiMo, и случилось переименование в Tizen.

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

    Взлететь оно, конечно, не взлетит — как и любая другая ОС, столь недружественно относящаяся к разработчику. Посему никакой речи о "будущем мобильной разработки" не ведется.
    Re[43]: Вот еще, или я, кажется, читать разучился
    От: jazzer Россия Skype: enerjazzer
    Дата: 28.02.13 04:09
    Оценка: 8 (2) +3
    Здравствуйте, alex_public, Вы писали:

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


    J>>Супер. Так если кодами ошибок не удобнее и не безопаснее, зачем обрабатывать ошибки ими?


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


    Можно твое так называемое "небольшое" озвучить в цифрах?

    J>>И что там насчет "прямой и модульной изначальной архитектуры" на кодах возврата? Или у тебя, кроме необоснованных заявлений, ничего нет?


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


    Show me the code.
    Пусть будет вот такой стек вызовов: read_profile -> load_files -> load_file -> read_file -> read_header -> read_field_group -> read_named_field -> read_integer.
    И у тебя вместо циферки встретилась буковка.
    Теперь расскажи нам про уровни и инкапсуляцию и прямую архитектуру и как тут будут рулить коды возврата.
    И имей в виду, что read_field_group зовет 50 разных read_named_field, read_header — 20 разных read_field_group, а load_files — 10 load_file.
    И заодно еще расскажи, как ты гарантируешь, что твой read_profile не вернет true в случае ошибки где-то в потрохах загрузки.

    Без этого дальнейший разговор не будет иметь никакого смысла.

    J>>Главное отличие исключений от кодов возврата в том, что коды возврата по умолчанию игнорируются, а исключения — наоборот.

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

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


    О да, это достойный аргумент


    _>>>Вреда правда тоже особого нет, разве что небольшое увеличение объёма кода.

    J>>Небольшое — это в два раза за счет "if(err)return err;" после каждой строчки
    _>Вообще то речь шла о том, что исключения дают небольшое увеличение объёма кода...
    По сравнению с чем? С ручным пробрасыванием кодов возврата? И у тебя, конечно же, есть результаты измерений?
    Плюс ты, наверное, говоришь только про объем бинарника, так как с полотенцами проверок кодов возврата в исходниках и так все понятно, правда?
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[51]: Вот еще, или я, кажется, читать разучился
    От: Patalog Россия  
    Дата: 28.02.13 05:56
    Оценка: +2
    Здравствуйте, alex_public, Вы писали:

    хъ

    _>Фокус в том, что если вы внимательно почитаете эту темку, то увидите что довольно много народа придерживается совсем другой позиции. А именно, что исключения надо использовать гораздо шире, чем описали вы. Вот с ними лично я тут и спорю понемногу. )))


    Нет здесь никакого противоречия.
    Код, которой кидает исключение\код возврата обычно не может предположить насколько фатально эта ошибка для программы в целом.
    Как вы это определите в нек. библиотеке, например? Такое возможно только в plain коде типа хелло ворлда, где все просматирвается насквозь.
    Если в требованиях к методу есть обработка фейла открытия пресловутого файла — он ее обработает, не важно через if или try.
    Если нет — сам кинет исключение.
    Почетный кавалер ордена Совка.
    Re[34]: Вот еще, или я, кажется, читать разучился
    От: Patalog Россия  
    Дата: 28.02.13 06:21
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    хъ

    P>>Ничем не отличается от исключений, кроме то, что в случае исключений мы можем на это забить, так как уровнем выше мы словим исключение по базе, а в твоем случае мы вынуждены пробрасывать\переформатировать, иначе потеряем ошибку и останемся в невалидном состоянии.


    _>Такие дела обычно приводят к нарушению инкапсуляции и т.п.. По нормальному каждый уровень кода должен оставлять все внутренние детали внутри себя.


    Это в любом случае лучше чем забы(и)ть про обработку кодов возврата.
    Кроме того, подход с сильно типизированными исключениями я не пробовал в боевом применении, дальше экспериментов дело не пошло.
    В то же время, мне сильно нравиться подход товарища zaufi, но пока все не сподоблюсь попробовать.
    У меня (к примеру) parse_error с указанием места фейла в потоке бит никому ничего не должен, он общий для неск. уровней иерархии вазовов.
    Возможно это нарушение инкапсуляции, но искусство ради искусства считаю не практичным.

    ЗЫ Про то как именно ты нормально оставляешь все детали кодов возврата внутри себя ты опять скромно умолчал. =)
    Почетный кавалер ордена Совка.
    Re[2]: Tizen 2.0
    От: clopomor  
    Дата: 28.02.13 06:51
    Оценка:
    Здравствуйте, SkyDance, Вы писали:

    SD>Теперь о том, откуда ноги растут у этого безобразия. "Вы не поверите" (С), но — из Intel. А туда, в свою очередь, попало после "перекрёстного опыления" Intel'овского поделия Moblin кодом из Maemo (кстати, в результате тяжелых родов получилось Meego, опять же, ожидаемо провалившаяся в силу тех же причин — "удобства" разработчиков портировать софт на этот вариант линукса).



    MeeGo — это как раз сплав из Moblin/Maemo (редхат подобная система c Zypper/RPM) — при чём то что на телефонах Nokia N9/N950 — то только Maemo 6 с изменённым названием на Meego Harmattan (Debian based dpkg/deb система).
    Разработка довольно простая, портирование тоже (Qt/QML/OpenGL/Clutter и тд.)
    И провалилось оно по политическим а не техническим причинам — не нужно было Микрософту конкурента в дополнение к Андроиду и иОС — соответственно НР слило WebOS викупив Палм а Nokia Maemo/MeeGo продавшись Микрософту.



    В Тизен основа Linaro с EFL/E17 вместо Qt.
    EFL сишная библиотека, соответственно обёртки над ней используют возврат кода ошибки, по моему логично.


    SD>Взлететь оно, конечно, не взлетит — как и любая другая ОС, столь недружественно относящаяся к разработчику. Посему никакой речи о "будущем мобильной разработки" не ведется.

    Добавляйте IMHO.Время покажет — у Самсунга ресурсы есть — сегмент Бады заменит точно.

    использовал Blackberry 7130 — Nokia 5800 — Palm pre+ — HTC Desire — Nokia N9 до сейчас.
    могу сравнивать.
    Re[46]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 28.02.13 08:08
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>А этот уровень разве не нужен при использовании кодов возврата?

    Нет. В случае отсутсвия исключений нужно обеспечить совсем другое соблдения по выходу из любой функции её постусловий. Это локальное требование, которое проще тестировать, например при модульном тестировании, проще обеспечивать, проще проверять статически и которое ВСЁ РАВНО надо обеспечивать...

    J>Аналогично не видно, обработали ли код возврата или это просто функция возвращает void, или если обработали, то все ли возможные значения обработаны.

    Этот элементарно делается статическим анализатором кода при комите, например...

    J>И что? Он будет точно таким же и с кодами возврата. И действия по восстановлению работоспособности программы будут точно такими же.

    Нет, не точно такими же. В случае исключений нам надо написать некий универсальный всемогутер, написанию которого, кроме всего прочего, ещё и сам язык С++ протвится, вернее его нереинтерабельная модель исключений.
    А в случае кода без исключений мы обычно имеем вполне перечислимый набор сценариев, которые надо обработать, и КОТОРЫЕ НАДО ПРОВЕРИТЬ.

    J>Как в таком случае насчет RAII и деструкторов? Они тоже зовутся в программе неявно

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

    J>Насчет нетестируемости — так трудно вызвать исключение?

    Всех типов во всех местах? Наверное нетрудно, если как-то автоматизировать это дело, только долго. И не понятно щачем. Кроме того, я не слышал, чт бы кто-то проводио такие тесты и не встречал подходящего для их провеения инструментария...

    А ты слышал? Вот в программах, в разработке которых ты принмал уастие наверняка декларировалась как минимум слабая гарантия. Так? Как проверялось, что она реально обеспечена, а не только задекларирована?..
    Мне такие прецеденты не известны. За исключением нескольких успешных попток переноса кода, при котором вылазили ошики, ясный пенью. И ВО ВСЕХ известных мне подробно случах переноса больших продуктов, выяснялось что базовая гарантия во многих местах нарушена на самом деле... При этом в некоторых нарушена так, что без весьма неыормального рефакторинга не чиниится, то есть гарантия не обеспечивалась даже на уровне архитектуры...
    Всё массовые коробочные или серверные продукты...

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

    J>Насчет труднопонимаемости — вообще не аргумент, имхо. Мне вот гораздо труднее установить корректность кода на кодах возврата.


    Да нет никаких особенностей у кодов возврата по сравнению с "просто функциями".
    Единственная особенность -- результаты некоторых типов нельзя просто терять. То есть некоторые функции нельзя вызвать как процедуры. Очень жаль, что в С/С++ нет возможность попросить компилятор проверять это дело, кстати. Но можно статический анализатор попросить, зато, что спасает.

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


    Тут есть две беды.
    1) С исключениями мы не можем об этом не беспокоиться. Мы должны беспокоиться об этом тоже, но не конкретно, а в общем. Весь разговор о том, при каких методах что проще. Обычно всемогутеры сложнее и ненадёжнее... А решения по месту в некоторых местах могут отсутствовать, но тут базовая гарантия ничем не лучше, наоборот хуже. Её наличие трунее проверить. а её требование к тому же, часто ещё и избыточно.

    2) Есть куча операций, которые не могут сфейлится пока не случилось фатального какого-то фейла.
    Те же рациональные числа, например. Чем деление на ноль в рац. числах так уж принципиально отличается от того же в double. Тем не менее double никаких С++ исключений не кидает и никто не жалуется вроде как...

    J>как return, а не как goto. Разницу видишь?

    Как long_jump, но с раскруткой стека, если быть строгими. Разницу между LJ и return видишь?..
    Разница в том, что в каждом конкретном месте мы не можем понять откуда мы сюда можем попасть. Множество "откуда" открытое... И множество "куда", на самом деле тоже. А с return всё не так. Попасть мы можем вообще только из одного места, а выйти можем только в точку возвратта их функции...

    просто пример, после вызова какой-о фцнкции я могу написать assert( мы выполнили постусловия );
    Как мне написать такой assert для случая с исключениями, например?..

    Я ещё раз повторяю, код в котором я не могу написать в каждм месте assert( если ещё не пора отгружать программу, то должно выполняться это ), является НЕПОНЯТНЫМ. В этом и состоит идея Дейкстры. Она очень мощная и продуктивная, позволяет писать много автоматических и полуавтоматических рантайм. статических и юнит-проверок. Это грандиозно удешевляет отладку, поддержку и является очень неплохой документацией, к тому же ещё и самопроверяющейся.
    Массовое использование исключений заставляет нас от этого отказаться. Ради чего?
    Вернее чем это предлагается заменить?..

    J>Замечательно. А теперь вспомним, что исключение — это по сути return, против которого ты ничего не имеешь.

    Нет, это, по сути динамически вычисляемый long jump, против которого я имею ОЧЕНЬ МНОГО!

    J>Ну фупмов теорией грузят в большом количестве.

    Прблемы -- факультет практиков и эксперементаторов, так что мимо

    J>спасибо, будет время — почитаю

    Очень советую. Безотносительно к исклчениям.

    J>Ну так код на исключениях элементарно переписывается на таковой на return'ах

    Нет, это не так. Смотри выше.

    J>ОК, минимальные условия, при которых операция даст нужный результат.

    Да, вернее это оператор, который по КУСКУ кода и его постусловию может вычислить такие предусловия. Да.

    J>Сорри, а почему тут предусловие программы (т.е. одно на всю программу), а не конкретного вызова? Очевидно, одни файлы критичны, а на другие можно и забить

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

    J>Так что у каждого вызова fopen свое постусловие, и соответственно свое соответствующее предусловие.

    Конечно. Но нас интересует же надёжность программы в целом, а не то, что этот вот конкретный fopen не упадёт?..
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[51]: Вот еще, или я, кажется, читать разучился
    От: Vzhyk  
    Дата: 28.02.13 09:42
    Оценка:
    On 28.02.2013 5:36, alex_public wrote:

    То есть предлагают на них организовывать логику программы? — это бред.
    Posted via RSDN NNTP Server 2.1 beta
    Re[2]: Tizen 2.0
    От: enji  
    Дата: 28.02.13 09:43
    Оценка: :))
    Здравствуйте, SkyDance, Вы писали:

    E>>Будущее мобильной разработки, Tizen 2.0. По моему, шикарно... 6 new, 3 каста, 1 delete и даже E_SUCCESS


    SD>Помнится, я в одном из форумов объяснял epic fail Symbian'а и тотальный уход в пользу iOS/Android именно подобным кодом и подходом к программированию вообще. Некоторые были не согласны, и превозносили Symbian как прекрасную ОС, якобы предательски убитую г-ном Элопом (и уже под это дело вагон теорий заговора).


    Мне кажется, тут ты не прав. Разработчик подтянется к любой ОСи, дружественной к нему или нет. Главное, чтобы ось была популярной у пользователей. Тот же win32 не слишком-то дружественен к разработчику, но тем не менее
    Re[48]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: igna Россия  
    Дата: 28.02.13 10:33
    Оценка: +1 -2
    Здравствуйте, jazzer, Вы писали:

    J>Мой формальный ответ такой: код на исключениях элементарно переписывается один-в-один на код с кодами возврата и return'ами, для которого все давно доказано (то, что множественные return'ы переписываются в гроздь if'ов, надеюсь, специально доказывать не надо?)


    "Код на исключениях элементарно переписывается один-в-один на код с кодами возврата и return'ами" — Вот конкретно это утверждение неплохо бы доказать, раз уж ответ "формальный". Ну и слово "элементарно" здесь точно лишнее, причем по двум причинам: 1) "формально" оно никакой смысловой нагрузки не несет; 2) неформально оно неверно, если код и переписывается, то отнюдь не элементарно.
    Re[49]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: jazzer Россия Skype: enerjazzer
    Дата: 28.02.13 10:59
    Оценка: +1 :)
    Здравствуйте, igna, Вы писали:

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


    J>>Мой формальный ответ такой: код на исключениях элементарно переписывается один-в-один на код с кодами возврата и return'ами, для которого все давно доказано (то, что множественные return'ы переписываются в гроздь if'ов, надеюсь, специально доказывать не надо?)


    I>"Код на исключениях элементарно переписывается один-в-один на код с кодами возврата и return'ами" — Вот конкретно это утверждение неплохо бы доказать, раз уж ответ "формальный". Ну и слово "элементарно" здесь точно лишнее, причем по двум причинам: 1) "формально" оно никакой смысловой нагрузки не несет; 2) неформально оно неверно, если код и переписывается, то отнюдь не элементарно.


    Таки элементарно: бросание исключения переписывается в виде установки глобального объекта исключения + return, пробрасывание исключения — проверка установленного исключения и return, если оно установлено и нету catch, а если catch есть — goto не него (вставляется после каждой операции, которая может бросить — для пущей формальности можно вставить вообще после каждой операции).

    Иными словами, код
    void g() {
      ...
      throw x;
      ...
    }
    void f() {
      ...
      g();
      ...
    }
    
    int main() {
      try {
        ...
        f();
        ...
      } catch(exception e) {
        ...
      }
    }

    элементарно переписывается в виде
    exception current_exception = NULL;
    
    void g() {
      ...
      current_exception = x;
      return;
      ...
    }
    
    void f() {
      ...
      g();
      if (current_exception) return;
      ...
    }
    
    int main() {
      do { // чисто чтоб goto не писать
        ...
        f();
        if (current_exception) break;
        ...
      } while(false);
      if (current_exception) {
        ...
        current_exception = NULL;
      }
    }
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[50]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: igna Россия  
    Дата: 28.02.13 11:25
    Оценка: :)
    Здравствуйте, jazzer, Вы писали:

    J>. . .
    J>void g() {
    J>  ...
    J>  current_exception = x;
    J>  return;
    J>  ...
    J>}
    J>. . .


    Это никакое не формальное доказательство.

    И этот код даже неверен, поскольку g может быть вызвана в твоем же обработчике исключения, поэтому перед присваиванием переменной current_exception нужно проверить ее значение.
    Re[18]: Вот еще, или я, кажется, читать разучился
    От: Mr.Delphist  
    Дата: 28.02.13 11:26
    Оценка: +1
    Здравствуйте, alex_public, Вы писали:

    _>Здравствуйте, Evgeny.Panasyuk, Вы писали:


    EP>>Редкий?

    EP>>Выделение памяти в приложении, внутри структур данных — это редкость?

    _>Редким является не выделения памяти, а ситуация когда оно даёт сбой. И из факта особенности этой ситуации следуют соответствующие выводы насчёт её обработки...


    Это как раз последствие нашей "разбалованности" парадигмой Win32 про виртуальное адресное пространство, массированое строительство азиатских заводов микроэлектроники и "memory is not a resource".

    Тут в комментариях выше уже справедливо указывали микроконтроллеры с набортной нерасширяемой памятью, щедрых 4 килобайта... И это реальность сегодняшнего дня, а не бородатые "во времена моей молодости 40 баксов за мегабайт". Да и на младшие Raspberry Pi народ ворчит, что младшие модели всё ж обделены памятью — чуть куда рыпнулся сверх плана, всё, счастье кончилось.

    К чему это я? А, выделение памяти без throw...
    Re[12]: Вот еще, или я, кажется, читать разучился
    От: Mr.Delphist  
    Дата: 28.02.13 11:29
    Оценка:
    Здравствуйте, alex_public, Вы писали:

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


    MTD>>Вот из Adobe Illustrator SDK, обрати внимание, как в середине чуваки сами запарились проверять код возврата и тупо забили на обработку ошибок:


    _>Посмотрел повнимательнее на ваш код... Ха, так это же как раз отличный пример того, о чём я говорил. Именно реализация такой логики (зря вы подумали что они забили в середине — это же очевидно логика такая) как раз и очень неудобна с помощью исключений.


    У нормальных людей такой SDK не должен был вообще скомпилиться (-Wall -Werror), поэтому никогда бы не вышел в свет...
    Re[48]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 28.02.13 11:36
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>Концептуально исключения — это просто сахар для кодов возврата (а errno будет еще более близкой аналогией).

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

    так там у них был такой классец, OpResult, у которого был operator bool и был перегруженный c собой в качестве аргумента,и ещё несколько перегрузокнесколькими типами + всякие доп. аргументы operator()

    Клиентский код, выглядел примерно так:
    OpResult foo( T3& res, ... )
    {
        OpResult _;
        T1 LocalVar1;
        _&&_( do1( args ) )
        && _( do2( args ) )
        && _( ( LocVar1 = expt ) != ErrValue/*, тут опциональная инфа по ишибке */ )
        && _( do3( args ) );
        for( T2 LocalVar2 = ...; _ && ...; ... ) {
             _&&_( do4( args ) )
             && _( do5( args ) );
        }
        T3 LocVar3;
        _&&_( do6( args ) )
        && _( ( LocVar3 = expt ) != ErrValue/*, тут опциональная инфа по ишибке */ )
        && _( do7( args ) )
        && _( res = ... )
    
        discard_if_nned( LocVar1 );
        return _;
    }
    В целом странненько, но к этим палочкам-скобочкам очень быстро привыкаешь. Обработку прозевать трудно...

    Сейчас, кстати, можно вообще какой-нибудь $ выбрать, например...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[28]: Вот еще, или я, кажется, читать разучился
    От: jazzer Россия Skype: enerjazzer
    Дата: 28.02.13 11:48
    Оценка: 1 (1)
    Здравствуйте, Erop, Вы писали:

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


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


    E>В смысле? конструктор обеспечивает базовую гарантию, деструктор обеспечивает некидание исключений. Что тут не так?

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

    E>А сравнить я предлагаю с кодом, который сам по себе гарантий не обеспечивает...

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

    J>>
    void reserve(size_t new_capacity)
    {
      char* old_buf = buf_;
      buf_ = new char[new_capacity*sizeof(T)]; // если new бросает - в объекте ничего не меняется
      capacity_ = new_capacity;
      const size_t orig_size = size_;
      size_=0;
      // итак, сейчас у нас buf_ указывает на нововыделенный пустой буфер
      // capacity соответствует его размеру и size_ нулевой (так как ничего в буфере нету)
      // Т.е. вектор уже в рабочем состоянии (пустой), базовая гарантия в плане инвариантов
      // УЖЕ выполнена (я ведь обещал, что это элементарно?)
    
      // Осталось разобраться с утечками.
      // Для этого в конце, независимо ни от чего, прибиваем old_buf со всем содержимым
      // (этот прибиватор вполне себе общего назначения и его можно объявить и снаружи):
      struct OnScopeExit {
        char* old_buf;
        size_t orig_size;
        ~OnScopeExit() {
          for (size_t i=0; i<orig_size; ++i) ((T&)( old_buf[i*sizeof(T)] )).~T();
          delete[] old_buf;
        }
      } on_scope_exit = { old_buf, orig_size };
      // все, базовая гарантия достигнута полностью, можно начинать изгаляться над буфером
    
      // попробуем покопировать, нехай исключения летят
      for (; size_<orig_size; ++size_)
        new (&buf_[size_*sizeof(T)]) T(std::move( (T&)old_buf[size_*sizeof(T)] ));
      // по окончании работы функции size_ показывает количество успешно скопированных объектов
    }

    Как я и обещал, все элементарно.

    E>Это сейчас ещё даже во многих популярных боевых компиляторах не заведётся...

    E>Может быть когда-нибудь, лет через пять-десять...
    Э, с чего бы это вдруг? BOOST_SCOPE_EXIT написан лет 5 как и тестировался на gcc3, который хз сколько лет везде крутится.
    Ну и лямбду я заюзал исключительно для краткости. То же самое элементарно достигается локальной структурой, просто писанины _чуть_ больше будет.

    E>Но даже то, что написано тут мне не нравится категоррически, очень мутно и сложно.

    Ну если это для тебя мутно и сложно, то я не знаю прям...
    ОК, я добавил там комментариев и по просьбам трудящихся избивался от лямбды и scope_exit.
    ассерты и проверки, которые у тебя там ниже, извини, вставлять не буду — лень.
    Все еще мутно и сложно?

    E>Ну давай всё равно почитаем...

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

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

    Что такое параллельные массивы? Ты уже второй раз их упоминаешь.

    J>>Давай теперь то же на кодах возврата. Особенно сексуально будут выглядеть коды возврата из конструктора неизвестного типа и их смешение с ошибкой выделения памяти для буфера.

    E>Там не будет std::vector'а, там надо как-то иначе.
    E>Например, у типа будет не конструктор перемещения, а перегруженная функция ERR_CODE move_array_item( T& dst, T& src ), которая вернёт, смогла или нет,..
    E>точный аналог втоего кода тогда будет выглядеть как-то так:
    ERR_CODE reserve( size_t new_capacity )
    E>{
    E>    ERR_CODE res = EC_Ok;  // это мантра ;)
    E>    if( new_capacity <= capacity_ ) { // Этого у тебя не было, но положим, 
    // что ты про это забыл потому что код очень простой и понятный ;)
    E>        return res;
    E>    }
    
    E>    assert( new_capacity > 0 ); 
    
    E>    // Создаём копию буфера, и передвигаем в неё данные
    E>    char* extra_buf = new char[new_capacity*sizeof(T)] );
    E>    if( extra_buf == 0 ) {
    E>        return EC_MemoryError;
    E>    }
        
    E>    size_t cp_size = 0;
    E>    while( cp_size < size() && IsOk( res ) ) {
    E>        res = move_array_item( ((T*)extra_buf)[cp_size], ((T*)buf_)[cp_size] );
    E>    }
    E>    // тут мы ещё можем решить, что разрушать. Например, можно разрушать
          // старый буффер только если полностью получилось скопировать новый
    E>    if( IsOk( res ) ) {
    E>        std::swap( extra_buf, buf_ );
    E>        std::swap( size_, cp_size );
    E>        capacity_ = new_capaciry;
    E>    }
    
    E>    while( cp_size  > 0 ) {
    E>        ( --cp_size + (T*)extra_buf )->~T();  // Разрушаю всё-таки с конца...
    E>    }  
    E>    delete[] extra_buf;
    E>    return res;
    E>}

    E>длиннее, но проще. + учтено чуть больше всяких мелочей и содно выбрать что в случае аварии делаем.
    Где ж проще? Я проверить new_capacity <= capacity_ забыл, да, но ты ж не будешь называть это ключевым отличием, я надеюсь
    А то я скажу, что у тебя cp_size в цикле не инкрементится
    Удалять с конца абсолютно бессмысленно, ибо нигде не сказано, что объекты вставлялись в вектор по порядку или что потом на них не было напущен sort.
    Так что "больше всяких мелочей" никакой рояли не играют в данном случае.

    E>Но это всё равно класс спректированный под исключения. Например, если мы вспомним, что ещё бывают всякие там insert и erase, которым надо сдвигать куски буфера, то у нас начнутся проблемы.

    Не начнутся.
    E>Либо нам надо будет написать походие циулы несколько раз. А всё потому, что мы не можем позволить себе иметь кусок памяти, где просто память и объекты перемешаны как попало...
    А функции на паре указателей для "похожих циклов" написать религия запрещает?

    E>Зато, если без исключений пишем, или пости без исключений, например, то можно функцию move_array_item сделать чуть прикольнее.

    E>}[/c] ну и для простоты ещё и такой:
    template<typename T> void destroy_array_of_items( T* dst, size_t count ) 
    E>{
    E>    while( count > 0 ) {
    E>        ( dst + --count )->~T();
    E>    }
    E>}

    Ну то есть мой OnScopeExit выше. Да, если писать реальный класс вектора, то многое уйдет во вспомогательные функции и все будет еще лаконичнее и у тебя, и у меня.


    E>Ну и с этой инфраструктурой мы легко можем теперь писать разные штуки вроде insert...

    E>Кстати, я так думал, что ты заведёшь внутри reserve ещё одну копию вектора, в котором зарезервируешь нужный буффер, потом перенесёшь элементы и обменяешь это всё.
    Зачем, если можно проще? Правда, для тебя это внезапно оказалось "мутно и сложно"

    E>>>Ну тогда покажи то же но про два параллельных массива, например...

    J>>это еще что? У тебя развлечение такое — мне задания на кодинг выдумывать?
    E>Я пытаюсь тебе показать, что сохранять инварианты в случае исключения весьма небесплатно. И даже гарантировать отсутствие утечек не всегда просто.
    Ничего не бывает бесплатно, если ты именно это хотел доказать, то ты не того адресата выбрал.

    J>>Ты не подменяй тему обсуждения, а... Речь шла о том, что код становится запутанным — я показал, что не становится.

    J>>Если хочешь обсудить оптимизацию и как она влияет на понятность кода — я готов. Заодно расскажешь, как замечательно делается аналогичная оптимизация на кодах возврата.
    E>Во-первых, я не сторонник кодов возврата, я всего лишь понимаю люедй, которые не хотят связываться с исключениями, так что я могу исказить позицию тру сторонников.
    E>Во-вторых, тему я не подменяю. Имелось же в виду "программы аналогичные по функционалу и эффективности", иначе смысла нет обсуждать. Ясен пень что и так и сяк можно написать просто, а можно сложно, можно эффективно, а можно неэффективно. Надо сравнивать эффективно и хорошо там и эффективно и хорошо там...
    Ну и где же твое "и там и там", если ты все время хочешь сравнить код с гарантиями с кодом без гарантий?

    E>>>2) Ничего клнцептуально сложного в нём, тем не менее нет, гарантии безопасности -- зна-а-а-ачительно сложнее концептуально

    J>>Да что ты говоришь. Убрать за собой в случае вылета исключения — это же так сложно.
    E>Конечно сложно, так как
    E>1) Вылет может произойти где угодно
    Да
    E>2) "Где угодно" вернуться к инвариантам всех данных во всей программе может быть трудно, если вообще возможно.
    Достаточно возвращаться в инвариантам локально и документировать, где у тебя какой уровень безопасности.
    E>А в это время может случиться какая-нибудь клизьма. Ну там деструктор какой-нибудь нежданно куда-то слазит, или ещё чего...
    э?

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

    E>Почему? Писать везде if( IsOk( res ) ) res = следующая_часть_обработки( параметры ); так уж сложно?

    Нет, не сложно. Объясни вот только теперь, почему в приведенном адобовском коде этого не написали?
    И почти везде в реальности забивают на повсеместную проверку кодов возврата, если только не применяются драконовские административные меры?
    ЗЫ Статический анализатор не поможет против того адобовского кода
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[52]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 28.02.13 12:09
    Оценка:
    Здравствуйте, Vzhyk, Вы писали:

    V>То есть предлагают на них организовывать логику программы? — это бред.


    Ну вроде как открытым текстом люди пишут...
    Вот читаем мы какой-то текстовый файл конфига. В одной строчке не ту циферку встретили -- кидаем исключение. Интересно, кстати, какое?..
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[3]: Tizen 2.0
    От: Erop Россия  
    Дата: 28.02.13 12:13
    Оценка: +1 :)
    Здравствуйте, enji, Вы писали:

    E>Мне кажется, тут ты не прав. Разработчик подтянется к любой ОСи, дружественной к нему или нет. Главное, чтобы ось была популярной у пользователей. Тот же win32 не слишком-то дружественен к разработчику, но тем не менее


    Фиг бы с ним, с win тридцать вторым! Уж на что УГ было АПИ у старой макоси, а писали жеж.
    Вообще разработчиков обычно, если это не бесплатный опенсорс, спрашивают не "нравится тебе ОС" или нет, а 2ты арплату получать хочешь?"
    просто если ОС особенно *своеобразная*, то зарплата должна быть чуть больше...

    и да, на мой взглаяд симбиан для телефона намногоболее удачная платформа, чем андроид.
    может на андроид легче перенести какое-нибудь большое приложение, но, зато, на симбиане телефоны хорошие получались, а не глюкавое УГ с рывками в интерфейсе и батарейкой на полдня...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[50]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 28.02.13 12:15
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>Иными словами, код

    J>
    J>void g() {
    J>  ...
    J>  throw x;
    J>  ...
    J>}
    J>void f() {
    J>  ...
    J>  g();
    J>  ...
    J>}
    
    J>int main() {
    J>  try {
    J>    ...
    J>    f();
    J>    ...
    J>  } catch(exception e) {
    J>    ...
    J>  }
    J>}
    J>

    J>элементарно переписывается в виде
    J>
    J>exception current_exception = NULL;
    
    J>void g() {
    J>  ...
    J>  current_exception = x;
    J>  return;
    J>  ...
    J>}
    
    J>void f() {
    J>  ...
    J>  g();
    J>  if (current_exception) return;
    J>  ...
    J>}
    
    J>int main() {
    J>  do { // чисто чтоб goto не писать
    J>    ...
    J>    f();
    J>    if (current_exception) break;
    J>    ...
    J>  } while(false);
    J>  if (current_exception) {
    J>    ...
    J>    current_exception = NULL;
    J>  }
    J>}
    J>


    Так мы не получим процедурного кода, тем не менее...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[53]: Вот еще, или я, кажется, читать разучился
    От: Vzhyk  
    Дата: 28.02.13 12:19
    Оценка:
    On 28.02.2013 15:09, Erop wrote:

    > Вот читаем мы какой-то текстовый файл конфига. В одной строчке не ту

    > циферку встретили -- кидаем исключение. Интересно, кстати, какое?..
    Абсолютно логично и правильно делают. Программа должна делать только то,
    что написано в требованиях и ни в коем случае не делать что-то другое.
    Но, есть момент, что если в требованиях написано, что если в
    конфигурации есть ошибки, то нужно сделать то-то и тот-то и продолжить
    работу, то и в этом случае я бы использовал исключение, ибо ситуация
    редкая и не входит в логику программы. Единственный момент, когда
    исключения не нужны: если у нас в программе зашита некая дефолтная
    конфигурация и мы должны ее использовать, если пользователь не установил
    значения некоторых параметров другими. Все.
    Posted via RSDN NNTP Server 2.1 beta
    Re[51]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: jazzer Россия Skype: enerjazzer
    Дата: 28.02.13 12:48
    Оценка: :)
    Здравствуйте, igna, Вы писали:

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


    I>
    J>>. . .
    J>>void g() {
    J>>  ...
         if (current_exception) std::terminate();
    J>>  current_exception = x;
    J>>  return;
    J>>  ...
    J>>}
    J>>. . .
    I>


    I>Это никакое не формальное доказательство.

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

    I>И этот код даже неверен, поскольку g может быть вызвана в твоем же обработчике исключения, поэтому перед присваиванием переменной current_exception нужно проверить ее значение.

    Теперь твоя душенька довольна?
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[51]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: jazzer Россия Skype: enerjazzer
    Дата: 28.02.13 12:49
    Оценка:
    Здравствуйте, Erop, Вы писали:

    E>Так мы не получим процедурного кода, тем не менее...

    Да фроде чифтый фортран
    А что "тем не менее"?
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[52]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 28.02.13 13:04
    Оценка: +1 -1 :)
    Здравствуйте, jazzer, Вы писали:

    E>>Так мы не получим процедурного кода, тем не менее...

    J>Да фроде чифтый фортран
    Это никак не гарантирует процедурности...

    J>А что "тем не менее"?


    ну ты пока что якобы показал, что программа с обработкой ошибок на исключениях эквивалентна некому весьма УГ коду, где куча инфы передаётся через статические переменные, а весь код утыкан конструкциями вида "если в какой-то статической переменной такое-то значение, то goto куда-то"...

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

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

    Теперь поясни мне, пожалуйста. Я чего-то не понял в твоей аргументации? Или оно на самом деле не эквивалентно? Или таки ты сам же и доказал, что программы с массовыми исключениями полный аналог сорвершенного говно-goto-нереинтерабельного кода?..
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[54]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 28.02.13 13:07
    Оценка:
    Здравствуйте, Vzhyk, Вы писали:

    V>Абсолютно логично и правильно делают. Программа должна делать только то,

    V>что написано в требованиях и ни в коем случае не делать что-то другое.

    Это логично только в том случае, если мы этот парсер для этой программы написали и забыли.
    Индустрия программирования же стремиться разрабатывать переиспользуемый код. поэтому неплохо бы, что бы код функции ReadInteger можно было бы использовать и в той программе, где по буковкам в таком поле надо дохнуть и втой, где надо сказать, "вы знаете, у вас там в профиле всё хорошо, но вместо уровня доходов написано "не скажу", бум работать с таким профилем?"...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[55]: Вот еще, или я, кажется, читать разучился
    От: Vzhyk  
    Дата: 28.02.13 13:12
    Оценка:
    On 28.02.2013 16:07, Erop wrote:

    > Индустрия программирования же стремиться разрабатывать переиспользуемый

    > код. поэтому неплохо бы, что бы код функции ReadInteger можно было бы
    > использовать и в той программе, где по буковкам в таком поле надо
    > дохнуть и втой, где надо сказать, "вы знаете, у вас там в профиле всё
    > хорошо, но вместо уровня доходов написано "не скажу", бум работать с
    > таким профилем?"...
    Опять перешли к сферическим коням. Не надоело еще?
    Индустрия программирования все, что делает — это выполняет различные
    заказы по программированию и совсем не заниматся стремлениями.
    Если заказчик оплатил различные извращения, то мы их будем делать, если
    не оплатил, но не будем, ибо Хроноса в родственниках ни у кого из нас
    нет и предсказать, что будет нужно не можем.
    Posted via RSDN NNTP Server 2.1 beta
    Re[56]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 28.02.13 14:02
    Оценка:
    Здравствуйте, Vzhyk, Вы писали:

    V>Индустрия программирования все, что делает — это выполняет различные

    V>заказы по программированию и совсем не заниматся стремлениями.

    Ещё есть и ретейл, вообще-то. Есть аппаратно-програмные комплексы и т. д...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[52]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: igna Россия  
    Дата: 28.02.13 14:10
    Оценка: +1 -1 :))
    Здравствуйте, jazzer, Вы писали:

    J>Теперь твоя душенька довольна?


    Ну по крайней мере теперь ты видишь, что "переписать код на исключениях на код с кодами возврата" вовсе не элементарно. "Элементарно" тут скорее сделать ошибку при этом переписывании.
    Re[51]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: igna Россия  
    Дата: 28.02.13 14:12
    Оценка:
    Здравствуйте, Erop, Вы писали:

    E>Так мы не получим процедурного кода, тем не менее...


    Структурного.
    Re[29]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 28.02.13 14:14
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>Нет, не сложно. Объясни вот только теперь, почему в приведенном адобовском коде этого не написали?

    потому, что им было пофиг на обработку ошибок, так же, как и пофиг при исключениях.
    Авторы приведённого кода думали, что "а, фигня, поправим, если вылезет при тестах", и те, кто якобы гарантии безопасности обеспечили, так же примерно думали, что пофиг вйона, главное манёвры...
    Ergo: если у руководства проекта нет политической воли, то на корректную обработку ошибок ФАКТИЧЕСКИ ЗАБИВАЮТ.

    Дальше возникает вопрос, если реально всё равно этого ничего нет, то на кой на это вообще ресурсы тратить? Для галочки?

    J>И почти везде в реальности забивают на повсеместную проверку кодов возврата, если только не применяются драконовские административные меры?

    И на РЕАЛЬНОЕ обеспечение гарантий тоже. Вот, например, в твоей команде, как проверяют то, что базовая гарантия безопасности реально обеспечена а не только продеклорирована?..

    J>ЗЫ Статический анализатор не поможет против того адобовского кода

    Зато статический анализатор + ипатьевский метод очень даже
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[52]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 28.02.13 14:17
    Оценка:
    Здравствуйте, igna, Вы писали:

    I>Структурного.

    Не важно как назвать. Важно, что получим ужос-ужос...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[2]: Tizen 2.0
    От: alex_public  
    Дата: 28.02.13 14:21
    Оценка:
    Здравствуйте, SkyDance, Вы писали:

    Не знаю про Tizen (не смотрел его ещё), но вот про MeeGo не надо. Это была вполне хорошая система как для пользователей (см. отзывы на N9), так и для разработчиков.
    Re[53]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: igna Россия  
    Дата: 28.02.13 14:47
    Оценка:
    Здравствуйте, Erop, Вы писали:

    E>Не важно как назвать.


    Да просто иногда под процедурным понимают императивное.
    Re[54]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 28.02.13 14:51
    Оценка: +1
    Здравствуйте, igna, Вы писали:

    I>Да просто иногда под процедурным понимают императивное.

    Ну Дейкстра вроде так обзывал, но это правда всё равно.
    Джаззер как бы показал, что код на исключениях эквивалентен полнейшему ужасу. Странно, что он считает это аргументом в защиту исключений...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[56]: Вот еще, или я, кажется, читать разучился
    От: igna Россия  
    Дата: 28.02.13 14:53
    Оценка:
    Здравствуйте, Vzhyk, Вы писали:

    V>Индустрия программирования все, что делает — это выполняет различные

    V>заказы по программированию и совсем не заниматся стремлениями.

    Ну это как-то однобоко. Даже MOP*-программисты стремятся к своей цели.

    *Money-oriented programming
    Re[44]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 28.02.13 14:56
    Оценка: -1 :)
    Здравствуйте, jazzer, Вы писали:

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

    J>Можно твое так называемое "небольшое" озвучить в цифрах?

    Сам сравни объём этого кода http://www.rsdn.ru/forum/cpp/5082655
    Автор: alex_public
    Дата: 26.02.13
    с этим http://www.rsdn.ru/forum/cpp/5082759
    Автор: Patalog
    Дата: 26.02.13
    плюс добавив код определения класса исключений.

    J>Show me the code.

    J>Пусть будет вот такой стек вызовов: read_profile -> load_files -> load_file -> read_file -> read_header -> read_field_group -> read_named_field -> read_integer.
    J>И у тебя вместо циферки встретилась буковка.
    J>Теперь расскажи нам про уровни и инкапсуляцию и прямую архитектуру и как тут будут рулить коды возврата.
    J>И имей в виду, что read_field_group зовет 50 разных read_named_field, read_header — 20 разных read_field_group, а load_files — 10 load_file.
    J>И заодно еще расскажи, как ты гарантируешь, что твой read_profile не вернет true в случае ошибки где-то в потрохах загрузки.

    Так это очень просто. И так read_integer у нас ругается на букву, не важно исключением или кодом возврата. Но коду использующему функцию read_file совершенно ни к чему знать из-за какой конкретно ерунды файл не читается корректно. Поэтому read_file должна отчитываться (кодом возврата или исключением) о удачном/неудачном прочтение файлa, без лишних подробностей. Аналогично и коду использующему read_profile должно быть абсолютно пофиг какой конкретно из файлов не прочитался. Думаю понятна логика?

    Соответственно у нас может быть 4 варианта:
    1. Тупой проброс кодов возврата с нижнего уровня — это не модульный говнкод.
    2. Автоматическая работа с исключениями с нижнего уровня — это не модульный говнкод, но чуть меньшего объёма чем вариант 1.
    3. Необходимая обработка кодов возврата на своём уровне, с возвратом осмысленных значений на каждом уровне. Это нормальный код.
    4. Работа через исключения с необходимой обработкой их на каждом уровне. Это нормальный код, но занимающий больший объём чем вариант 3.

    _>>Вообще то речь шла о том, что исключения дают небольшое увеличение объёма кода...

    J>По сравнению с чем? С ручным пробрасыванием кодов возврата? И у тебя, конечно же, есть результаты измерений?

    Про тупое пробрасывание кодов возврата я уже вроде всё написал.

    J>Плюс ты, наверное, говоришь только про объем бинарника, так как с полотенцами проверок кодов возврата в исходниках и так все понятно, правда?


    Объём бинарника вообще никого не волнует — мы тут не про микроконтроллеры говорим как бы.
    Re[52]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 28.02.13 14:58
    Оценка:
    Здравствуйте, Patalog, Вы писали:

    P>Нет здесь никакого противоречия.

    P>Код, которой кидает исключение\код возврата обычно не может предположить насколько фатально эта ошибка для программы в целом.
    P>Как вы это определите в нек. библиотеке, например? Такое возможно только в plain коде типа хелло ворлда, где все просматирвается насквозь.
    P>Если в требованиях к методу есть обработка фейла открытия пресловутого файла — он ее обработает, не важно через if или try.
    P>Если нет — сам кинет исключение.

    Библиотеки — это отдельный разговор. Думаю что там правильнее всего реализовывать оба варианта (если это не слишком напряжно). Как во многих частях Boost например.
    Re[35]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 28.02.13 15:05
    Оценка: +1
    Здравствуйте, Patalog, Вы писали:

    P>Это в любом случае лучше чем забы(и)ть про обработку кодов возврата.

    P>Кроме того, подход с сильно типизированными исключениями я не пробовал в боевом применении, дальше экспериментов дело не пошло.
    P>В то же время, мне сильно нравиться подход товарища zaufi, но пока все не сподоблюсь попробовать.
    P>У меня (к примеру) parse_error с указанием места фейла в потоке бит никому ничего не должен, он общий для неск. уровней иерархии вазовов.
    P>Возможно это нарушение инкапсуляции, но искусство ради искусства считаю не практичным.

    Хыхы, а я эту новую темку пропустил как-то... Спасибо, сейчас почитаем, почитаем... )))

    А модульность (и инкапсуляция как один из инструментов её реализации) как очень полезна именно на практике, а не в теории. Причём что интересно не для какого-то абстрактного повторного использования кода, а именно для качества изначального.
    Re[52]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 28.02.13 15:07
    Оценка:
    Здравствуйте, Vzhyk, Вы писали:

    V>То есть предлагают на них организовывать логику программы? — это бред.


    Нуу не то что бы всю логику через исключения... А скажем так "неудачу функции" какой-то возвращать через исключения, хотя исполнение программы эта неудача нисколько не прерывает... Вот с этим я не согласен.
    Re[19]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 28.02.13 15:11
    Оценка:
    Здравствуйте, Mr.Delphist, Вы писали:

    MD>Это как раз последствие нашей "разбалованности" парадигмой Win32 про виртуальное адресное пространство, массированое строительство азиатских заводов микроэлектроники и "memory is not a resource".


    MD>Тут в комментариях выше уже справедливо указывали микроконтроллеры с набортной нерасширяемой памятью, щедрых 4 килобайта... И это реальность сегодняшнего дня, а не бородатые "во времена моей молодости 40 баксов за мегабайт". Да и на младшие Raspberry Pi народ ворчит, что младшие модели всё ж обделены памятью — чуть куда рыпнулся сверх плана, всё, счастье кончилось.


    MD>К чему это я? А, выделение памяти без throw...


    Ну да) Но у микроконтроллеров исключения тоже обычно забанены, только совсем по другим причинам. ))) Там вообще чаще чистый C. Хотя лично я всё равно предпочитаю C++ использовать, благо для моих любимых микроконтроллеров есть компилятор почти со всеми возможностями.
    Re[36]: Вот еще, или я, кажется, читать разучился
    От: Patalog Россия  
    Дата: 28.02.13 16:07
    Оценка: +2 :)
    Здравствуйте, alex_public, Вы писали:

    хъ

    _>А модульность (и инкапсуляция как один из инструментов её реализации) как очень полезна именно на практике, а не в теории.

    _>Причём что интересно не для какого-то абстрактного повторного использования кода, а именно для качества изначального.

    Убавьте пафос, вы тут пока только больше говорите, а все просьбы показать как оно "на самом-то деле" правильно скромно скипаете.
    Почетный кавалер ордена Совка.
    Re[37]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 28.02.13 16:27
    Оценка:
    Здравствуйте, Patalog, Вы писали:

    P>Убавьте пафос, вы тут пока только больше говорите, а все просьбы показать как оно "на самом-то деле" правильно скромно скипаете.


    Я несколько раз показал, как правильно. Мне каждый раз ответили, что это сферические кони в вакууме.
    Думаешь стоит продолжить попытки?..
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[44]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 28.02.13 17:25
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>Show me the code.

    J>Пусть будет вот такой стек вызовов: read_profile -> load_files -> load_file -> read_file -> read_header -> read_field_group -> read_named_field -> read_integer.
    J>И у тебя вместо циферки встретилась буковка.

    Я верно понимаю, что тебе кажется, что верное решение на исключениях будет типа все всё увлечённо читают, а потом из read_profile вылетает "вместо циферки встретилась буковка"?..

    J>Теперь расскажи нам про уровни и инкапсуляцию и прямую архитектуру и как тут будут рулить коды возврата.


    Тут вообще не булет кодов возврата в обчном понимании.
    Будет такой примерно код.
    xxxfile src_file;
    yyyfile_header src_header;
    if( !src_file.open( file_name ) ) {
       // тут какая-то обработка того, что типа нету, скажем такая:
       src_header.ResetToDefault();
       if( !src_file.create( file_name ) || !src_header.write_back( src_file ) ) {
           return fatalAccessError; 
       }
    } else if( !src_header.ReadAndParse( src_file ) ) {
       // тут обработка чего там у нас не parse.
       // например, если поле необязательное, то выставляем в объекте ptofile списко варнингов о формате, но работаем дальше, если нет, то возвращаем ошибку, что типа формат существенно не тот, решаёте там сверху, чего делать.
    };
       // тут так же читаем сам файл
       return success;
    }

    при этом не забываем, ещё, что обычно это всё не функция read_profile, а метод объекта CProfile, например конструктора. Или там read? скажем. Так что мы можем распилить его на подметоды + выставлять то, что провалилось, а что нет в самом объекте.

    J>И имей в виду, что read_field_group зовет 50 разных read_named_field, read_header — 20 разных read_field_group, а load_files — 10 load_file.


    ну и что? Про каждый пишем считать, и анализируем результат. За одно проверяем
    1) Обязательное ли это поле, или так, мелочи, и
    2) Можем ли пропустить это поле до конца.
    если у нас ещё и формат профиля такой, что даже если чего-то не читается, всё равно обычно можем пропустить, то всё считаем, проанализаируем и сможем юзать.

    Вызывающий код будет выглядеть так:
    bool init_profile( CProfile& profile ) {.
        profile.Read();
        while( 1 ) {
            switch( profile.Status() ) {
            case CProfile::ST_Ready: {
                return true;
            }  break;   
            case CProfile::ST_ConditionalReady: {
                // тут анализаируем годится нам такие проблемы или нет.
                // если годиться, 
                     profile.ResetFieldsWithWarningsToDefault();
                     profile.DiscardWarnings();
                     return true;
                // если не годиться, то , например, спрашиваем пользователя что делать^
                //   сбросить профиль в деволт или всё отменить?
                //   в зависимости от действуем
            }  break;   
            case CProfile::ST_OccupyByOtherProcess: {
                // тут тоже что-то делаем, ждём там или проваливаемся или другой процесс выталкиваем;
            } break;   
            case CProfile::ST_FatalAccessError: {
                //  отправляем пользователя за админом
            }  break;   
            assert( false );
        }
    }


    А как это будет выглядеть на исключениях?..

    J>И заодно еще расскажи, как ты гарантируешь, что твой read_profile не вернет true в случае ошибки где-то в потрохах загрузки.

    Статическим анализатором кода...

    J>>>Главное отличие исключений от кодов возврата в том, что коды возврата по умолчанию игнорируются, а исключения — наоборот.

    Это не совсем так. Форсировать проверку возвратов можно довольно легко просто добавив статический анализатор при коммите, например.
    мало того, если уж обсуждать, что бы было более полечно в С -- исключения, или возможность сказать про функцию, что её результат обязательно должен быть использован в месте вызова, то второе однозначно полезнее и прямее ну и очень сильно проще
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[29]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 28.02.13 17:28
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>Тогда можно, но это уже инвариант "указатель всегда указывает на память, которую можно безопасно delete"


    Обычно у С++ объектов есть ещё какие-то инварианты, кроме того, что можно позвать деструктор...

    J>Т.е. у которого даже деструктор позвать нельзя? Инварианты же нарушены, например, указатель может указывать хз куда, а ты ему delete. Это какой-то патологический случай.


    Нет. Например, строка. Деструктор позвать можно, но длина инициализирована неверно, терминирующего нуля нет и т. д...

    J>Как я и обещал, все элементарно.

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

    J>Э, с чего бы это вдруг?

    Лямбды, как бэ, сэр...

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


    Ага, ещё *чуть* больше... Так вот курочка по зёрнышку...

    J>ОК, я добавил там комментариев и по просьбам трудящихся избивался от лямбды и scope_exit.

    Я понял всё, что там написано. Просто это довольно сложный код.
    Скажем так, уровень программиста, который адекватно там всё поймёт и в случае чего найдёт и ВЕРНО поправит багу довольно высокий...

    J>Можно было бы вообще все прибить, но оставить то, что можно оставить, мне кажется полезнее.

    Почему полезнее?.. Для чего полезнее? В каком сценарии это принесёт пользу и какую?..

    J>Что такое параллельные массивы? Ты уже второй раз их упоминаешь.

    В одном лежат коды букв в редакторе, а в другом из цвета. Синхронизация по индексу.

    J>Где ж проще?

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

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

    J>Удалять с конца абсолютно бессмысленно, ибо нигде не сказано, что объекты вставлялись в вектор по порядку или что потом на них не было напущен sort.

    J>Так что "больше всяких мелочей" никакой рояли не играют в данном случае.

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

    J>А функции на паре указателей для "похожих циклов" написать религия запрещает?

    А как мы в такой функции обеспечим инварианты вектора, если у него буфер будет "с дырками"?..

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

    J>Ну то есть мой OnScopeExit выше. Да, если писать реальный класс вектора, то многое уйдет во вспомогательные функции и все будет еще лаконичнее и у тебя, и у меня.


    Ну да. И у меня останется вообще просто такой довольно код, типа
    if( !сделать_то_то() )
        подчистить_так_то()
    .
    А у тебя в чём-то эквивалентный, но со скоупгардами или с try|catch...

    J>Зачем, если можно проще? Правда, для тебя это внезапно оказалось "мутно и сложно"

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

    J>Ничего не бывает бесплатно, если ты именно это хотел доказать, то ты не того адресата выбрал.

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

    J>Ну и где же твое "и там и там", если ты все время хочешь сравнить код с гарантиями с кодом без гарантий?


    Ну так надо сравнивать сколько будет стоить ПОЛНЫЙ цикл жизни ПО в той парадигме и в другой... А какие ещё варианты?
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[3]: Tizen 2.0
    От: SkyDance Земля  
    Дата: 28.02.13 22:22
    Оценка:
    E>Мне кажется, тут ты не прав. Разработчик подтянется к любой ОСи, дружественной к нему или нет. Главное, чтобы ось была популярной у пользователей. Тот же win32 не слишком-то дружественен к разработчику, но тем не менее

    На момент своего появления и активного развития Win32 был лучшим API. Впрочем, как и Win16. Потому что API других ОС был еще сложнее, запутаннее и с неудобными средствами разработки. Дело же не только в API, но и в средствах разработки в целом — debugger, IDE, ....
    Re[4]: Tizen 2.0
    От: SkyDance Земля  
    Дата: 28.02.13 22:24
    Оценка:
    E>может на андроид легче перенести какое-нибудь большое приложение, но, зато, на симбиане телефоны хорошие получались, а не глюкавое УГ с рывками в интерфейсе и батарейкой на полдня...

    Узнаю Erop'а. Можно даже на ник автора не смотреть, и так ясно, кто пишет.
    Конечно, это большое достоинство Симбиана, в том, что Нокиа умеет делать хорошие телефоны.

    А под Андроид (в момент его появления и популяризации) действительно было удобнее писать, чем в это же время под Симбиан (где уже был зоопарк устройств с разными версиями, экранами, библиотеками и железом).
    Re[30]: Вот еще, или я, кажется, читать разучился
    От: SkyDance Земля  
    Дата: 28.02.13 22:27
    Оценка:
    E>Ну да. И у меня останется вообще просто такой довольно код, типа
    if( !сделать_то_то() )
    E>    подчистить_так_то()
    .

    E>А у тебя в чём-то эквивалентный, но со скоупгардами или с try|catch...

    Как мне кажется, подобное ретроградство в итоге приведет к... reinventing the wheel, то бишь, те же exceptions, но — "свои", без поддержки компилятором syntax sugar, без хороший оптимизации, да еще и с багами.
    Re[53]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: jazzer Россия Skype: enerjazzer
    Дата: 28.02.13 23:08
    Оценка: :)
    Здравствуйте, igna, Вы писали:

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


    J>>Теперь твоя душенька довольна?


    I>Ну по крайней мере теперь ты видишь, что "переписать код на исключениях на код с кодами возврата" вовсе не элементарно. "Элементарно" тут скорее сделать ошибку при этом переписывании.


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


    Он имел нахальство рассказывать в моем присутствии о жителях планеты Борелии из звездного роя в Орионе; он говорил, что живут там чудовища величиною с гору, называемые Медлитами за неслыханную медлительность их жизненных процессов, вызванную низкой температурой и оледенелостью планеты.

    – Представьте себе, – говорил он, – что когда в Египте царствовал Аменготеп Четвертый из Фиванской династии, на Борелии встретились два Медлита. Один из них спросил: «Что нового?» После этого были сооружены Пирамиды, Александр Македонский покорил Азию и дошел до Тихого океана; Греция была покорена Римом; образовалась Римская империя германского народа; шли крестовые походы; ислам боролся с христианством; кипели войны Алой и Белой Розы, Тридцатилетняя война, Столетняя война… а другой Медлит все еще не отвечал, и только когда немцы победили Францию под Седаном, борелианское чудовище ответило: «Ничего нового…» Так невероятно, неслыханно медленно протекает жизнь этих поразительных созданий; я могу сказать это спокойно, ибо сам их видел и исследовал.

    Тут терпение у меня иссякло.

    – То, что вы рассказали, – холодно произнес я, – это низкая ложь.

    Став центром всеобщего внимания, я объяснил:

    – Александр Великий никогда не доходил до Тихого океана, ибо, как хорошо известно, вернулся с пути в 325 году до нашей эры.

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

    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[53]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: jazzer Россия Skype: enerjazzer
    Дата: 28.02.13 23:23
    Оценка: +3
    Здравствуйте, Erop, Вы писали:

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


    E>>>Так мы не получим процедурного кода, тем не менее...

    J>>Да фроде чифтый фортран
    E>Это никак не гарантирует процедурности...

    J>>А что "тем не менее"?


    E>ну ты пока что якобы показал, что программа с обработкой ошибок на исключениях эквивалентна некому весьма УГ коду, где куча инфы передаётся через статические переменные, а весь код утыкан конструкциями вида "если в какой-то статической переменной такое-то значение, то goto куда-то"...

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

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

    Причем тут УГ? Ты разве о красоте кода хотел поговорить или о принципиальной переписываемости стиля А в стиль Б, для которого все доказано?

    E>IMHO, ты только продемонстрировал мой тезис, что код на исключениях эквивалентиен совершеннийшеё лапше из goto по статичесием ппеременным, что само по себе ужасно, и с чем именно и боролся Дейкстра, когда предлагал процедурное программирование...

    Открой для себя дизассемблер, там сплошные goto.

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

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

    Почему ты все время подменяешь тему разговора, причем тобой же заданную? Начал с доказуемости, кончил рассуждениями про УГ
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[55]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: jazzer Россия Skype: enerjazzer
    Дата: 01.03.13 02:55
    Оценка: 1 (1) +1
    Здравствуйте, Erop, Вы писали:

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


    I>>Да просто иногда под процедурным понимают императивное.

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

    А ведь прикинь, народу достаточно того, что что-то там эквивалентно машине Тьюринга, независимо от того, какой там "ужас-ужас" на машине Тьюринга получается.
    А ты, вишь, вот каким эстетом оказался...
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[5]: Tizen 2.0
    От: Erop Россия  
    Дата: 01.03.13 08:43
    Оценка:
    Здравствуйте, SkyDance, Вы писали:

    SD>Узнаю Erop'а. Можно даже на ник автора не смотреть, и так ясно, кто пишет.

    Походу ты ко мне неравнодушен. Остынь, коллега я не по этим делам...

    SD>Конечно, это большое достоинство Симбиана, в том, что Нокиа умеет делать хорошие телефоны.

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

    Видимо это же тоже входит в сикд "умеет делать хорошие телефоны"?
    Проблемы андроида связаны же не с тем, что телефоны плохие, а с тем, что там асинхронно, всё, параллельно, да ещё и не риал тайм даже близко. Отсюда и рывки и то, что компик надо целиком в воздух поднять, что бы секунду на часах перещёлкнуть и т. д.
    Андроид, конечно, пилят, но когда допилят --
    Опять же юзабилити оболочки ниде всякого плинтуса. Все мои частые сценарии использования телефона сделаны неудобно ВСЕ -- значит тупо все, без исклчения. Зато удобно сделаны свистелки и гуделки...

    SD>А под Андроид (в момент его появления и популяризации) действительно было удобнее писать, чем в это же время под Симбиан (где уже был зоопарк устройств с разными версиями, экранами, библиотеками и железом).


    Ну, то есть сейчас всех винфон порвёт? Под него же пока нет зоопарка утройств?..
    А уж Tizen-то просто вне конкуренции будет
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[31]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 01.03.13 08:46
    Оценка:
    Здравствуйте, SkyDance, Вы писали:

    SD>Как мне кажется, подобное ретроградство в итоге приведет к... reinventing the wheel, то бишь, те же exceptions, но — "свои", без поддержки компилятором syntax sugar, без хороший оптимизации, да еще и с багами.


    Мне вот правда очент интерсно, что такое сделали с современными инженерами, что вернуть бул из процедуры им кажется менее простым, прямым и удачным решением, чем писать явно только самый частый сценарий, а остальные рассовывать по каким-то срабатывающим по событиям обработчикам?
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[54]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 01.03.13 09:03
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>Э-э-э....

    Согласись, что ты показал, тем не менее квивалентность УГ, что само по себе является странным аргументом...

    J>Надеюсь, не надо доказывать, что от статических переменных можно элементарно избавиться, передавая их всюду (как это делается в функциональных языках, там для этого даже спецсахар есть в виде монад)?

    Ты думаешь это упростит код?..
    Проблема статических переменных не в том, что они хранятся где-то не там, а в том, что отовсюду видны, то есть сильно повышают степень зависимости частей программы между собой.
    От того, что указатель на такую переменную ты получишь как аргумент, а не из таблицы символов линкера как бы не поменется вообще НИЧЕГО...
    Это с точки зрения доказуемости обсуждаемого кода, если, а не с точки зрения монад...

    Ну для того, куда ты переписал как раз точно и доказано, что это УГ...

    J>Открой для себя дизассемблер, там сплошные goto.

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

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


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

    J>Почему ты все время подменяешь тему разговора, причем тобой же заданную? Начал с доказуемости, кончил рассуждениями про УГ


    Прости, если лишняя резкоость моих формулировок сбила тебя.
    Под УГ я имел в виду недоказуемость, неверифицируемость и вообще труднопонимаемость.
    Так что тема всё та же. Знает кто-то удобную математическую модель кода с исключениями или её пока не придумали (возможно её и нельзя вообще придумать, фиг его знает)...

    Подход Дейкстры AKA процедурное программирование на программах с исключениями НЕ РАБОТАЕТ.
    Нужен какой-то другой подход...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[48]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 01.03.13 09:07
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>Э-э-э....

    Согласись, что ты показал, тем не менее эквивалентность кода с исклюениями УГ определённого вида, что само по себе является странным аргументом...

    J>Надеюсь, не надо доказывать, что от статических переменных можно элементарно избавиться, передавая их всюду (как это делается в функциональных языках, там для этого даже спецсахар есть в виде монад)?

    Ты думаешь это упростит код?..
    Проблема статических переменных не в том, что они хранятся где-то не там, а в том, что отовсюду видны, то есть сильно повышают степень зависимости частей программы между собой. (проблема исклюений, кстати говоря, ровно та же)
    От того, что указатель на такую переменную ты получишь как аргумент, а не из таблицы символов линкера как бы не поменется вообще НИЧЕГО...
    Это с точки зрения доказуемости обсуждаемого кода, если, а не с точки зрения монад...

    Ну для того, куда ты переписал как раз точно и доказано, что это УГ...

    J>Открой для себя дизассемблер, там сплошные goto.

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

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


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

    J>Почему ты все время подменяешь тему разговора, причем тобой же заданную? Начал с доказуемости, кончил рассуждениями про УГ


    Прости, если лишняя резкоость моих формулировок сбила тебя.
    Под УГ я имел в виду недоказуемость, неверифицируемость и вообще труднопонимаемость.
    Так что тема всё та же. Знает кто-то удобную математическую модель кода с исключениями или её пока не придумали (возможно её и нельзя вообще придумать, фиг его знает)?..

    Подход Дейкстры AKA процедурное программирование на программах с исключениями НЕ РАБОТАЕТ.
    Нужен какой-то другой подход...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[56]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 01.03.13 09:13
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>А ведь прикинь, народу достаточно того, что что-то там эквивалентно машине Тьюринга, независимо от того, какой там "ужас-ужас" на машине Тьюринга получается.

    J>А ты, вишь, вот каким эстетом оказался...

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

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

    То есть обсуждать применимо ли оно или нет просто бессмысленно. То, что оно неприменимо -- это математический факт. Дльше можно обсуждать какие-то модификации процедурного программирования, или какие-то вообще совсем альтернативные походы, но о установленных фактах спорить смысла нет.
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[54]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: igna Россия  
    Дата: 01.03.13 09:17
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>Став центром всеобщего внимания, я объяснил:

    ...............................................

    J>Раздались рукоплескания, ....................


    Что-то ты замечтался совсем.
    Re[53]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: jazzer Россия Skype: enerjazzer
    Дата: 01.03.13 09:17
    Оценка: -1
    Здравствуйте, igna, Вы писали:

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


    J>>Теперь твоя душенька довольна?


    I>Ну по крайней мере теперь ты видишь, что "переписать код на исключениях на код с кодами возврата" вовсе не элементарно. "Элементарно" тут скорее сделать ошибку при этом переписывании.


    О, на сей раз ты твой слив выражаешь расставлением смайликов? А чего не минусов, ты ж обычно при помощи минусования сублимируешь? Или весна?
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[55]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: jazzer Россия Skype: enerjazzer
    Дата: 01.03.13 09:27
    Оценка:
    Здравствуйте, Erop, Вы писали:

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


    J>>Э-э-э....

    E>Согласись, что ты показал, тем не менее квивалентность УГ, что само по себе является странным аргументом...
    То есть эквивалентность я показал, ты с этим согласен. Уже прогресс.
    Теперь объясни толком, чем он тебе не процедурный.

    J>>Надеюсь, не надо доказывать, что от статических переменных можно элементарно избавиться, передавая их всюду (как это делается в функциональных языках, там для этого даже спецсахар есть в виде монад)?

    E>Ты думаешь это упростит код?..
    Это уничтожит статические переменные — это ведь они тебя напрягают по неведомой причине

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

    E>От того, что указатель на такую переменную ты получишь как аргумент, а не из таблицы символов линкера как бы не поменется вообще НИЧЕГО...
    Ее можно передавать по значению всюду, так что указатели и линкеры не при делах вообще.

    J>>Открой для себя дизассемблер, там сплошные goto.

    E>Я не знаею, как тебе ещё объяснить, я тебе уже и ссылки давал и сам пересказывал...
    E>Процедурность определяется не наличием или отсутствием goto там или ассемблера, а структурой потока управления в программе и выполняемыми в этом потоке действиями.
    E>Ты сам понимаешь, что программа с исключениями изоморфна в некотором смысле программе в том стиле, который ты предложил. И таки да, она не процедурна. Почему ты не можешь этого понять или принять для меня загадка...
    Потому что я не вижу, что она не процедурна, а ты это никак не обосновываешь. Что именно делает ее непроцедурной? Наличие статической переменной? Я уже сказал, как от нее избавиться. Еще что-то?

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


    E>Видимо это различное понимание терминов. Я под процедурным программированием имел в виду то же, что и Дейкстра в "Дисциплине программирования", а не то, что программу можно выразить на паскале...

    Ткни тогда пальцем, пожалуйста, где непроцедурность в переписанном коде.

    J>>Почему ты все время подменяешь тему разговора, причем тобой же заданную? Начал с доказуемости, кончил рассуждениями про УГ


    E>Прости, если лишняя резкоость моих формулировок сбила тебя.

    E>Под УГ я имел в виду недоказуемость, неверифицируемость и вообще труднопонимаемость.
    Ткни пальцем. Я вот помню, что Дейкстра утверждал, что наличие goto делает программу недоказуемой.
    При этом имелся в виду goto в стиле бейсика, когда можно откуда угодно куда угодно, не взирая на границы процедур.
    Я не помню, чтобы он что-то говорил про недоказуемость условий и циклов.
    В моем переписанном коде только условия и циклы.
    Что я понимаю не так?
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[54]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: igna Россия  
    Дата: 01.03.13 09:33
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    JJ>А чего не минусов


    здесь
    Автор: igna
    Дата: 28.02.13
    Re[55]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: jazzer Россия Skype: enerjazzer
    Дата: 01.03.13 09:42
    Оценка: :)
    Здравствуйте, igna, Вы писали:

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


    JJ>>А чего не минусов


    I>здесь
    Автор: igna
    Дата: 28.02.13


    А, так это ты мне так за мой смайлик мстишь, и "мстя твоя страшна"?
    Извини, пожалуйста, что задел твою тонкую душевную организацию, наградив ничтожным смайликом твое исполненное высочайшего смысла сообщение.
    Ну хочешь, я уберу его, раз тебе так лихо?
    Вот, уже убрал, видишь, уже все хорошо!
    Не расстраивайся так, ты у нас умничка и мы тебя очень любим!
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[57]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: jazzer Россия Skype: enerjazzer
    Дата: 01.03.13 09:44
    Оценка:
    Здравствуйте, Erop, Вы писали:

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


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


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


    Объясни, плиз, на пальцах, раз уж ты так в теме, почему твой код с кодами возврата процедурный, а мой с ними же (переписанный из исключений, и без статической переменной, если это критично) — нет.
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[56]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 01.03.13 09:47
    Оценка: +1
    Здравствуйте, jazzer, Вы писали:

    J>Теперь объясни толком, чем он тебе не процедурный.

    Я же сказал. Массовое использование goto...

    E>>От того, что указатель на такую переменную ты получишь как аргумент, а не из таблицы символов линкера как бы не поменется вообще НИЧЕГО...

    J>Ее можно передавать по значению всюду, так что указатели и линкеры не при делах вообще.
    Если ты будешь передавать её по значению, то как снаружи функции узнают о том, что случилсоь внутри?..

    J>Потому что я не вижу, что она не процедурна,

    А ты попробуй такую программу ДОКАЗАТЬ, сразу всё увидишь...

    J>Ткни тогда пальцем, пожалуйста, где непроцедурность в переписанном коде.

    Уже много раз ткнул...

    J>Я не помню, чтобы он что-то говорил про недоказуемость условий и циклов.

    J>В моем переписанном коде только условия и циклы.
    J>Что я понимаю не так?
    В смысле? А куда делись goto на обработчики исключений?...

    Понимаешь, мы, конечно можем передавать указатели на контекст и размножить все обработчики, что бы избежать goto и т. д. Но мы тогда получим программу, которая ОЧЕНЬ СИЛЬНО сложнее исходной.
    При этом польза от процедурного программирования состоит в том, что мы имеем возможность понятным образом связывать работоспособность кода с условиями на состояние программы.

    Окей, вот мы размножили все catch'и так, словно каждый оператор завёрнут в свой индивидуальный try{}catch, и даже смогли вычислить wp от постусловия программы для содержимого всех этих catch...
    Как теперь эту кучу предикатов склеить обратно в предикат для того catch, который мы пишем реально?..

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

    Я понима, как получить из кода с исключениями эквивалентный на кодах возвратов и goto, так скажем, но он будет непроцедурный. Я понимаю, как введением очень массового размножения кода и массовы же return из середины функций, написать в каком-то смысле эквивалентный и процедурный, но этот эквивалентный и процедурный будет ОЧЕНЬ СЛОЖНЫМ. И не понятно как его свернуть обратно в относительно простой. То есть как по предикатам этого "эквивалентнго" кода восстановать аналогичные предикаты для исходного?

    В принципе мы можем, конечно, работать с кодом с исключениями, как с этаким шаблоном, который надо интерпретировать как краткую запись того вот самого сверхраждутого варианта кода. Но тогда мы автоматом признаём, что код с исключениями ТАК ЖЕ СЛОЖЕН, как тот раздутый код. А тот раздутый код ОЧЕНЬ СЛОЖЕН...

    Но мне кажется, что это слишком формальный взгляд на вещи, и реально исключения усложняют код, но не так катастрофически, а вот понять как именно они усложняют, почему и нсколько это усложнение вообще необходимо (может есть стратегии использования, при которых усложнения нет или оно маленькое, например) не получается. И похоже не только у меня одного...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[57]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: jazzer Россия Skype: enerjazzer
    Дата: 01.03.13 10:14
    Оценка:
    Здравствуйте, Erop, Вы писали:

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


    J>>Теперь объясни толком, чем он тебе не процедурный.

    E>Я же сказал. Массовое использование goto...
    Где ты у меня увидел goto? Ну хоть один?

    E>>>От того, что указатель на такую переменную ты получишь как аргумент, а не из таблицы символов линкера как бы не поменется вообще НИЧЕГО...

    J>>Ее можно передавать по значению всюду, так что указатели и линкеры не при делах вообще.
    E>Если ты будешь передавать её по значению, то как снаружи функции узнают о том, что случилсоь внутри?..
    И возвращать по значению, как код возврата, вестимо.

    J>>Потому что я не вижу, что она не процедурна,

    E>А ты попробуй такую программу ДОКАЗАТЬ, сразу всё увидишь...
    Достаточно показать сводимость к к программе, которую ты можешь доказать.
    Более того, те же исключения на монадах в функциональных языках замечательно доказываются математически.

    J>>Ткни тогда пальцем, пожалуйста, где непроцедурность в переписанном коде.

    E>Уже много раз ткнул...

    J>>Я не помню, чтобы он что-то говорил про недоказуемость условий и циклов.

    J>>В моем переписанном коде только условия и циклы.
    J>>Что я понимаю не так?
    E>В смысле? А куда делись goto на обработчики исключений?...
    Они переписались в условия и циклы. Для которых все доказано сами Дейкстрой, не?

    E>Понимаешь, мы, конечно можем передавать указатели на контекст и размножить все обработчики, что бы избежать goto и т. д. Но мы тогда получим программу, которая ОЧЕНЬ СИЛЬНО сложнее исходной.

    Исходной — это какой? С исключениями? или с кодами возврата?
    Как насчет юниксового errno, кстати? Он процедурный?

    E>При этом польза от процедурного программирования состоит в том, что мы имеем возможность понятным образом связывать работоспособность кода с условиями на состояние программы.

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

    E>Окей, вот мы размножили все catch'и так, словно каждый оператор завёрнут в свой индивидуальный try{}catch, и даже смогли вычислить wp от постусловия программы для содержимого всех этих catch...

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

    E>Суть же подхода Дейкстры состоит в том, что мы можем записать условие того, попадём мы в постусловие программы или нет для любого места в программе, и при этом условие не будет зависеть от пути, по которому мы в это место попали. Только от значений переменных и всё.

    С исключениями то же самое. Если ты попал в catch, то тебе совершенно поровну, откуда прилетело исключение — из самого кода функции или из кода на 10 уровней ниже. Объект исключения может быть разным, только и всего.

    E>Я понима, как получить из кода с исключениями эквивалентный на кодах возвратов и goto, так скажем, но он будет непроцедурный. Я понимаю, как введением очень массового размножения кода и массовы же return из середины функций, написать в каком-то смысле эквивалентный и процедурный, но этот эквивалентный и процедурный будет ОЧЕНЬ СЛОЖНЫМ. И не понятно как его свернуть обратно в относительно простой. То есть как по предикатам этого "эквивалентнго" кода восстановать аналогичные предикаты для исходного?

    Где он ОЧЕНЬ СЛОЖНЫЙ? Ты это серьезно, что ли?
    Ну и меня порадовало выделенное. Оговорку "в каком-то смысле" я тебе великодушно прощаю, раз уж ты признаешь, что можно его переписать в эквивалентный процедурный, т.е. для любого кода на исключениях существует эквивалентный процедурный код, к которому применима в полном объеме теория Дейкстры.

    E>В принципе мы можем, конечно, работать с кодом с исключениями, как с этаким шаблоном, который надо интерпретировать как краткую запись того вот самого сверхраждутого варианта кода. Но тогда мы автоматом признаём, что код с исключениями ТАК ЖЕ СЛОЖЕН, как тот раздутый код. А тот раздутый код ОЧЕНЬ СЛОЖЕН...

    В каком месте мой переписанный код ОЧЕНЬ СЛОЖНЫЙ?

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

    Слушай, тебе не угодишь. То ты требуешь формальной эквивалентности, то говоришь, что это слишком формальный взгляд на вещи
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[45]: Вот еще, или я, кажется, читать разучился
    От: jazzer Россия Skype: enerjazzer
    Дата: 01.03.13 10:27
    Оценка: +1
    Здравствуйте, alex_public, Вы писали:

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


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

    J>>Можно твое так называемое "небольшое" озвучить в цифрах?

    _>Сам сравни объём этого кода http://www.rsdn.ru/forum/cpp/5082655
    Автор: alex_public
    Дата: 26.02.13
    с этим http://www.rsdn.ru/forum/cpp/5082759
    Автор: Patalog
    Дата: 26.02.13
    плюс добавив код определения класса исключений.


    J>>Show me the code.

    J>>Пусть будет вот такой стек вызовов: read_profile -> load_files -> load_file -> read_file -> read_header -> read_field_group -> read_named_field -> read_integer.
    J>>И у тебя вместо циферки встретилась буковка.
    J>>Теперь расскажи нам про уровни и инкапсуляцию и прямую архитектуру и как тут будут рулить коды возврата.
    J>>И имей в виду, что read_field_group зовет 50 разных read_named_field, read_header — 20 разных read_field_group, а load_files — 10 load_file.
    J>>И заодно еще расскажи, как ты гарантируешь, что твой read_profile не вернет true в случае ошибки где-то в потрохах загрузки.

    _>Так это очень просто. И так read_integer у нас ругается на букву, не важно исключением или кодом возврата. Но коду использующему функцию read_file совершенно ни к чему знать из-за какой конкретно ерунды файл не читается корректно. Поэтому read_file должна отчитываться (кодом возврата или исключением) о удачном/неудачном прочтение файлa, без лишних подробностей. Аналогично и коду использующему read_profile должно быть абсолютно пофиг какой конкретно из файлов не прочитался.


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

    _>Думаю понятна логика?


    Понятна, конечно. Называется "выбрасываем с водой ребенка". Я прямо так и представляю себе, заполняешь ты форму, скидываешь на диск, запускаешь прогу, а она тебе: " У Вас в файле неонка ошибка, а где конкретно — не скажу, ибо мне совершенно ни к чему знать из-за какой конкретно ерунды файл не читается корректно, ищи сам".

    J>>И заодно еще расскажи, как ты гарантируешь, что твой read_profile не вернет true в случае ошибки где-то в потрохах загрузки.

    Вот этот вопрос остался без ответа.

    _>Соответственно у нас может быть 4 варианта:

    _>1. Тупой проброс кодов возврата с нижнего уровня — это не модульный говнкод.
    _>2. Автоматическая работа с исключениями с нижнего уровня — это не модульный говнкод, но чуть меньшего объёма чем вариант 1.
    _>3. Необходимая обработка кодов возврата на своём уровне, с возвратом осмысленных значений на каждом уровне. Это нормальный код.
    _>4. Работа через исключения с необходимой обработкой их на каждом уровне. Это нормальный код, но занимающий больший объём чем вариант 3.
    Последний пункт неплохо бы доказать.
    Я правильно понимаю, что у тебя уровень===функция, и на одном уровне вложенных вызовов функций не бывает в принципе?

    J>>Плюс ты, наверное, говоришь только про объем бинарника, так как с полотенцами проверок кодов возврата в исходниках и так все понятно, правда?

    _>Объём бинарника вообще никого не волнует — мы тут не про микроконтроллеры говорим как бы.

    Тогда обработка кодов ошибок сливает исключениям просто-таки со страшной силой, ибо код распухает до полнейшей нечитаебльности.
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[58]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 01.03.13 12:38
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>>>Теперь объясни толком, чем он тебе не процедурный.

    E>>Я же сказал. Массовое использование goto...
    J>Где ты у меня увидел goto? Ну хоть один?
    У тебя он называется break...

    J>Достаточно показать сводимость к к программе, которую ты можешь доказать.

    То, к чему ты сводишь доказать довольно трудно. Например, где будем брать ограничивающую функцию циклов?
    J>Они переписались в условия и циклы. Для которых все доказано сами Дейкстрой, не?
    Не. Чтобы цикл был доказуем, он должен обладать рядом свойств. Что цикл
    for( int i = 5; i-- > 0; i++ ) { std::cout << i << std::endl; }
    попадает в какое-то постусловиие ты никак не докажешь...

    J>Как насчет юниксового errno, кстати? Он процедурный?\

    Не знаю точно. Скорее всего да.

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

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

    J>Ну и меня порадовало выделенное. Оговорку "в каком-то смысле" я тебе великодушно прощаю, раз уж ты признаешь, что можно его переписать в эквивалентный процедурный, т.е. для любого кода на исключениях существует эквивалентный процедурный код, к которому применима в полном объеме теория Дейкстры.

    Да, только он очень сложный при этом. Это делает весь подход бессмысленным.

    J>В каком месте мой переписанный код ОЧЕНЬ СЛОЖНЫЙ?

    Большой.

    J>Слушай, тебе не угодишь. То ты требуешь формальной эквивалентности, то говоришь, что это слишком формальный взгляд на вещи


    Я непонятно выразился? Если мы пойдём по этому пути, то получим, что иключения -- это просто ужос-ужос, как сложно, а на практике мы видим, что это сложнее "просто кода", конечно, но не в сотни раз...
    Значит мы просто неудачный формализм использовали, а не реальную сложность задачи смотрели. Сложность формализации превысила сложность задачи.
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[58]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 01.03.13 13:18
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    J>Объясни, плиз, на пальцах, раз уж ты так в теме, почему твой код с кодами возврата процедурный, а мой с ними же (переписанный из исключений, и без статической переменной, если это критично) — нет.


    Потому, что в твоём есть фейковые циклы с break'ами, при этом у этих циклов нет ни инвариантов ни ограничивающих функций...

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

    Но, если мы работаем с сиключениями мы ОБЫЧНО, делаем не так, и ты тоже дела не так.
    Мы говорим, что любое исключение может вылететь из любого места, то есть и мест выхода из функции становится больше и мест, где надо проверять коды вохврата больше и вариантов того, что могут и в каких конкретно случаях вернуть становится бесконечно много, строго говоря, и если мы начинаем переписывать код в таких предположениях, то он сильно усложняется, а в предикатаз появляется открытая часть (или ошибка произвольного типа, произошедшая в произвольном месте)...

    Собственно этот вот переход от явно перечисленных мест/причин провалу к открытому множеству того и другого и делает программу малопонятной и труднодоказуемой, если вообще доказуемой.
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[2]: Tizen 2.0
    От: Ziaw Россия  
    Дата: 01.03.13 15:08
    Оценка:
    Здравствуйте, UA, Вы писали:

    UA>Пропустили вызов

    UA>
    UA>map.Destruct();
    UA>

    UA>

    И
    pMapEnum->Construct()

    ?
    Re[46]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 01.03.13 17:06
    Оценка: :)
    Здравствуйте, jazzer, Вы писали:

    J>Понятна, конечно. Называется "выбрасываем с водой ребенка". Я прямо так и представляю себе, заполняешь ты форму, скидываешь на диск, запускаешь прогу, а она тебе: " У Вас в файле неонка ошибка, а где конкретно — не скажу, ибо мне совершенно ни к чему знать из-за какой конкретно ерунды файл не читается корректно, ищи сам".


    Ох, и почему очевидные вещи надо разъяснять на пальцах... Ну ок, раз не выходит в общем, объясню на конкретном примере. Ты хочешь подробные описания ошибок для пользователя? Ну так с помощью исключений это будет СЛОЖНЕЕ сделать при нормальной архитектуре и вообще невозможно при так любимой тобою "автоматической".

    Значит смотрим на твой же конкретный пример (стек вызовов: read_profile -> load_files -> load_file -> read_file -> read_header -> read_field_group -> read_named_field -> read_integer). Как я понимаю при автоматическом сценарии (это то, что ты вроде как пропагандируешь и то что я назвал немодульным говнокодом) у нас read_integer кидает исключение, а ловится оно где-то вокруг read_profile. Ну так в таком случае мы можем сказать пользователю только то, что "где-то вместо цифры встретила буква" и всё! Мы даже имя файла сообщить не сможем, т.к. ни read_integer, ни код вокруг read_profile его не знает. Не говоря уже о каких-то ещё деталях типа имени поля. Вот такие дела при говнокоде с автоматическими исключениями.

    Если же мы захотим сделать нормальный код, но на исключениях, то нам придётся ставить промежуточные обработчики исключений на каждом уровне, кидающие при этом сами другие исключения (действующие на другом уровне и содержащие другую информацию). Т.е. блоки try/catch/throw размножатся по всей этой цепочке и на каждом уровне будут исключения своего типа. Это безусловно будет корректно работать, но по объёму кода очевидно будет превосходить вариант с просто кодами возврата, не привнося при этом ни единого преимущества над ними.

    _>>Соответственно у нас может быть 4 варианта:

    _>>1. Тупой проброс кодов возврата с нижнего уровня — это не модульный говнкод.
    _>>2. Автоматическая работа с исключениями с нижнего уровня — это не модульный говнкод, но чуть меньшего объёма чем вариант 1.
    _>>3. Необходимая обработка кодов возврата на своём уровне, с возвратом осмысленных значений на каждом уровне. Это нормальный код.
    _>>4. Работа через исключения с необходимой обработкой их на каждом уровне. Это нормальный код, но занимающий больший объём чем вариант 3.
    J>Последний пункт неплохо бы доказать.

    Что там доказывать то? При одинаковом количестве блоков, очевидно что try/catch+определение класса исключения займёт больше места чем банальный if. А насчёт количества блоков смотри выше.

    J>Я правильно понимаю, что у тебя уровень===функция, и на одном уровне вложенных вызовов функций не бывает в принципе?


    Формально не обязательно, но на практике чаще всего так и выходит.
    Re[47]: Вот еще, или я, кажется, читать разучился
    От: maxkar  
    Дата: 01.03.13 17:33
    Оценка: +1
    Здравствуйте, alex_public, Вы писали:

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


    J>>Понятна, конечно. Называется "выбрасываем с водой ребенка". Я прямо так и представляю себе, заполняешь ты форму, скидываешь на диск, запускаешь прогу, а она тебе: " У Вас в файле неонка ошибка, а где конкретно — не скажу, ибо мне совершенно ни к чему знать из-за какой конкретно ерунды файл не читается корректно, ищи сам".


    _>Ох, и почему очевидные вещи надо разъяснять на пальцах... Ну ок, раз не выходит в общем, объясню на конкретном примере. Ты хочешь подробные описания ошибок для пользователя? Ну так с помощью исключений это будет СЛОЖНЕЕ сделать при нормальной архитектуре и вообще невозможно при так любимой тобою "автоматической".


    _>Значит смотрим на твой же конкретный пример (стек вызовов: read_profile -> load_files -> load_file -> read_file -> read_header -> read_field_group -> read_named_field -> read_integer). Как я понимаю при автоматическом сценарии (это то, что ты вроде как пропагандируешь и то что я назвал немодульным говнокодом) у нас read_integer кидает исключение, а ловится оно где-то вокруг read_profile. Ну так в таком случае мы можем сказать пользователю только то, что "где-то вместо цифры встретила буква" и всё! Мы даже имя файла сообщить не сможем, т.к. ни read_integer, ни код вокруг read_profile его не знает. Не говоря уже о каких-то ещё деталях типа имени поля. Вот такие дела при говнокоде с автоматическими исключениями.


    Все там нормально. Только исключения нужно на правильный уровень выносить. Показываю на java, потому что без разницы в данном контексте.
    int readIntField(String name, Stream stream) throws BadFieldException, IOException {
      try {
        return stream.readIntField();
      } catch (ForamtException e) {
        throw new BadFieldException(name, stream.offset(), e);
      }
    }
    
    FieldGroup readFieldGroup(Stream stream) throws BadFieldGroup, IOException {
      try {
        String f1 = readStringField("f1", stream);
        int f2 = readIntField("f2", stream);
      } catch (BadFieldException e) {
        throw new BadFieldGroup(e);
      }
    }


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

    _>Если же мы захотим сделать нормальный код, но на исключениях, то нам придётся ставить промежуточные обработчики исключений на каждом уровне, кидающие при этом сами другие исключения (действующие на другом уровне и содержащие другую информацию). Т.е. блоки try/catch/throw размножатся по всей этой цепочке и на каждом уровне будут исключения своего типа. Это безусловно будет корректно работать, но по объёму кода очевидно будет превосходить вариант с просто кодами возврата, не привнося при этом ни единого преимущества над ними.


    На практике здесь всего три уровня исключений. На read_profile: ProfileException с наследниками MissingProfileException и MailformedProfileException. На read_file: IOException (файл не читается, файл не существует) и BadFormatException (частный наследник IOException). В read_* те же IOException и BadFormatException. За исключением специальных случаев этого достаточно. Не полезет пользователь вручную править файл в нужном месте (и в код, чтобы понять, что же там было нужно). Он просто обратится к разработчику, а там уже можно и все восстановить. Большой плюс, если runtime позволяет stack trace развернуть. По stack trace (разработчику) обычно ясно, в каком же именно месте произошла ошибка.

    _>Что там доказывать то? При одинаковом количестве блоков, очевидно что try/catch+определение класса исключения займёт больше места чем банальный if. А насчёт количества блоков смотри выше.

    Пожалуйста, приведите мой же пример (те же два уровня) с сохранением той же информации об ошибках — имени поля и имени структуры, где произошла ошибка. И все это — на кодах ошибок, пожалуйста. Заметьте, что типы ошибок вам также придется описывать (ну не влезают нужные данные в код возврата). Ну и на лесенку if'ов (и переоборачивание) хочется посмотреть. Представьте еще, что в readFieldGroup читается 10 полей, а не два. На сколько сильно изменится ваш код? Кстати, мой код различает ошибки "файл не считался потому что диск начал сыпаться" и "файл имеет неправильный формат" (оба с нужной информацией).
    Re[48]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 02.03.13 01:43
    Оценка:
    Здравствуйте, maxkar, Вы писали:

    _>>Вот такие дела при говнокоде с автоматическими исключениями.

    M>Все там нормально. Только исключения нужно на правильный уровень выносить. Показываю на java, потому что без разницы в данном контексте.

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

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


    Такой код получается далеко не во всех случаях. К примеру если мы читаем вариативный конфиг, то там легко возможна ситуация когда например неудача readIntField не означает испорченный конфиг. Соответственно мы получим код, где внутри одной функции будет куча вызовов readIntField обвешанных персональными try/catch... Кстати, вот как раз java код обычно и славится такими соплями...

    M>Пожалуйста, приведите мой же пример (те же два уровня) с сохранением той же информации об ошибках — имени поля и имени структуры, где произошла ошибка. И все это — на кодах ошибок, пожалуйста. Заметьте, что типы ошибок вам также придется описывать (ну не влезают нужные данные в код возврата). Ну и на лесенку if'ов (и переоборачивание) хочется посмотреть. Представьте еще, что в readFieldGroup читается 10 полей, а не два. На сколько сильно изменится ваш код? Кстати, мой код различает ошибки "файл не считался потому что диск начал сыпаться" и "файл имеет неправильный формат" (оба с нужной информацией).


    Да одно объявление классов этих исключений, с их полями и конструкторами, перекроет любые if'ы по объёму. Что касается "типов ошибок" в варианте с кодами возвратов, то даже так с ходу и не припомню видел ли я такое чудо вообще когда-нибудь. )))
    Re[31]: Это-то как раз просто решается...
    От: ambel-vlad Беларусь  
    Дата: 02.03.13 01:54
    Оценка:
    Здравствуйте, Erop, Вы писали:

    X>>на протяжении всего треда, я вижу лишь обратное. (в реальности-то, оно давно обосновано и доказано)

    E>Смотри, ты пишешь же на С++ и с исключениями, и весь твой код обеспечивает как минимум базовую гарантию безопасности?

    E>Если ты так или иначе работаешь в команде, то предлагаю тебе эксперимент.

    E>Объявляешь приз в 100 баксов за каждый выявленный в твоём коде случай нарушения базовой гарантии и башляешь до тех пор, пока не расстанешься с иллюзиями

    КО говорит, что неиспользование исключений не избавляет от этой проблемы. Посему спрашивается, к чему это было?
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[47]: Вот еще, или я, кажется, читать разучился
    От: jazzer Россия Skype: enerjazzer
    Дата: 02.03.13 04:28
    Оценка: +2
    Здравствуйте, alex_public, Вы писали:

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


    J>>Понятна, конечно. Называется "выбрасываем с водой ребенка". Я прямо так и представляю себе, заполняешь ты форму, скидываешь на диск, запускаешь прогу, а она тебе: " У Вас в файле неонка ошибка, а где конкретно — не скажу, ибо мне совершенно ни к чему знать из-за какой конкретно ерунды файл не читается корректно, ищи сам".


    _>Ох, и почему очевидные вещи надо разъяснять на пальцах... Ну ок, раз не выходит в общем, объясню на конкретном примере.

    Ну наконец-то. Сейча мы увидим сияющий код, правда?

    _>Ты хочешь подробные описания ошибок для пользователя? Ну так с помощью исключений это будет СЛОЖНЕЕ сделать при нормальной архитектуре и вообще невозможно при так любимой тобою "автоматической".


    _>Значит смотрим на твой же конкретный пример (стек вызовов: read_profile -> load_files -> load_file -> read_file -> read_header -> read_field_group -> read_named_field -> read_integer). Как я понимаю при автоматическом сценарии (это то, что ты вроде как пропагандируешь и то что я назвал немодульным говнокодом) у нас read_integer кидает исключение, а ловится оно где-то вокруг read_profile. Ну так в таком случае мы можем сказать пользователю только то, что "где-то вместо цифры встретила буква" и всё! Мы даже имя файла сообщить не сможем, т.к. ни read_integer, ни код вокруг read_profile его не знает. Не говоря уже о каких-то ещё деталях типа имени поля. Вот такие дела при говнокоде с автоматическими исключениями.


    Мда. Погугли про chained exceptions, что ли. Аргументация уровня детского сада, честное слово.

    _>Если же мы захотим сделать нормальный код, но на исключениях, то нам придётся ставить промежуточные обработчики исключений на каждом уровне, кидающие при этом сами другие исключения (действующие на другом уровне и содержащие другую информацию). Т.е. блоки try/catch/throw размножатся по всей этой цепочке и на каждом уровне будут исключения своего типа. Это безусловно будет корректно работать, но по объёму кода очевидно будет превосходить вариант с просто кодами возврата, не привнося при этом ни единого преимущества над ними.


    Show me the code. Твое голословное "очевидно" не катит.

    _>>>Соответственно у нас может быть 4 варианта:

    _>>>1. Тупой проброс кодов возврата с нижнего уровня — это не модульный говнкод.
    _>>>2. Автоматическая работа с исключениями с нижнего уровня — это не модульный говнкод, но чуть меньшего объёма чем вариант 1.
    _>>>3. Необходимая обработка кодов возврата на своём уровне, с возвратом осмысленных значений на каждом уровне. Это нормальный код.
    _>>>4. Работа через исключения с необходимой обработкой их на каждом уровне. Это нормальный код, но занимающий больший объём чем вариант 3.
    J>>Последний пункт неплохо бы доказать.

    _>Что там доказывать то? При одинаковом количестве блоков, очевидно что try/catch+определение класса исключения займёт больше места чем банальный if. А насчёт количества блоков смотри выше.


    Show me the code. Твое голословное "очевидно" не катит.

    Ну и ты в который раз игнорируешь вопрос:
    J>>И заодно еще расскажи, как ты гарантируешь, что твой read_profile не вернет true в случае ошибки где-то в потрохах загрузки.
    "Очевидно" (с), потому что нечего сказать.
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[49]: Вот еще, или я, кажется, читать разучился
    От: jazzer Россия Skype: enerjazzer
    Дата: 02.03.13 04:33
    Оценка: +1
    Здравствуйте, alex_public, Вы писали:

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


    _>>>Вот такие дела при говнокоде с автоматическими исключениями.

    M>>Все там нормально. Только исключения нужно на правильный уровень выносить. Показываю на java, потому что без разницы в данном контексте.

    _>Естественно нормально, вы же тут как раз нормальную архитектуру нарисовали, а не "автоматическую". Так что с этим вопросов нет, вопросы в сравнение объёма работы для реализации такого и для варианта без исключений...


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

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


    _>Такой код получается далеко не во всех случаях. К примеру если мы читаем вариативный конфиг, то там легко возможна ситуация когда например неудача readIntField не означает испорченный конфиг. Соответственно мы получим код, где внутри одной функции будет куча вызовов readIntField обвешанных персональными try/catch... Кстати, вот как раз java код обычно и славится такими соплями...


    Для этих случаев пишутся специальные функции, очевидно. Типа readIntField(field, default).

    M>>Пожалуйста, приведите мой же пример (те же два уровня) с сохранением той же информации об ошибках — имени поля и имени структуры, где произошла ошибка. И все это — на кодах ошибок, пожалуйста. Заметьте, что типы ошибок вам также придется описывать (ну не влезают нужные данные в код возврата). Ну и на лесенку if'ов (и переоборачивание) хочется посмотреть. Представьте еще, что в readFieldGroup читается 10 полей, а не два. На сколько сильно изменится ваш код? Кстати, мой код различает ошибки "файл не считался потому что диск начал сыпаться" и "файл имеет неправильный формат" (оба с нужной информацией).


    _>Да одно объявление классов этих исключений, с их полями и конструкторами, перекроет любые if'ы по объёму. Что касается "типов ошибок" в варианте с кодами возвратов, то даже так с ходу и не припомню видел ли я такое чудо вообще когда-нибудь. )))


    Я так и из всего этого словоблудия не понял, будет демонстрация того, как замечательно пробрасывается вся необходимая информация на кодах возврата или нет?
    Тебя же попросили привести код. Не, никак? Не кодируется сегодня?
    jazzer (Skype: enerjazzer) Ночная тема для RSDN
    Автор: jazzer
    Дата: 26.11.09

    You will always get what you always got
      If you always do  what you always did
    Re[32]: Это-то как раз просто решается...
    От: Erop Россия  
    Дата: 02.03.13 16:55
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

    E>>Если ты так или иначе работаешь в команде, то предлагаю тебе эксперимент.

    E>>Объявляешь приз в 100 баксов за каждый выявленный в твоём коде случай нарушения базовой гарантии и башляешь до тех пор, пока не расстанешься с иллюзиями

    AV>КО говорит, что неиспользование исключений не избавляет от этой проблемы. Посему спрашивается, к чему это было?


    Обсуждался довольно простой вопрос -- обеспечивается ли азовая гарантия В РЕАЛНОСТИ...
    Исключения тут правда не при чём. Просто если исключения летают редко, то становится сильно менее важно, обеспечивается базовая гарантия или нет
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[50]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 02.03.13 17:08
    Оценка: :)
    Здравствуйте, jazzer, Вы писали:

    J>Для этих случаев пишутся специальные функции, очевидно. Типа readIntField(field, default).


    Ага, которая и будет реализована через те самые try/catch, т.к. нижележащая функция у нас работает через исключения...

    J>Я так и из всего этого словоблудия не понял, будет демонстрация того, как замечательно пробрасывается вся необходимая информация на кодах возврата или нет?

    J>Тебя же попросили привести код. Не, никак? Не кодируется сегодня?

    Ну приведи реальный (а не как у тебя были перед этим с исключениями гуляющими с нижнего уровня) рабочий пример с исключениями. Только полный пример, со всеми throw, try/catch и определениями классов исключений. А я тогда запишу его без исключений и сравним размер.
    Re[49]: Вот еще, или я, кажется, читать разучился
    От: maxkar  
    Дата: 02.03.13 17:30
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    _>Естественно нормально, вы же тут как раз нормальную архитектуру нарисовали, а не "автоматическую". Так что с этим вопросов нет, вопросы в сравнение объёма работы для реализации такого и для варианта без исключений...


    Так вы же сами просили "ошибки подробно" описывать. И говорили, что на кодах ошибок это проще, чем на исключениях . И я в предыдущем сообщении показывал, как это будет "по-умолчанию" с тремя уровнями исключений (без дополнительной обертки в readFieldGroup и т.п.). Завернуть все в unchecked и отлавливать на верхнем уровне тоже можно, но во вполне конкретных случаях и понимая, зачем и что с этим делать. Я за проработку обработки ошибок на ранних стадиях. Поэтому переоборачивание ошибок на границах слоев абстрации для меня — действие по умолчанию. Все исключения методов должны быть только в терминах интерфейса. Поэтому абстрактный ProfileService не может принципиально выбрасывать IOException. ProfileException — может. ProfileNotFound — может. А вот IOException — никогда.

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


    _>Такой код получается далеко не во всех случаях. К примеру если мы читаем вариативный конфиг, то там легко возможна ситуация когда например неудача readIntField не означает испорченный конфиг. Соответственно мы получим код, где внутри одной функции будет куча вызовов readIntField обвешанных персональными try/catch... Кстати, вот как раз java код обычно и славится такими соплями...


    Не будет. jazzer правильный пример привел. Для опциональных полей будут опциональные обертки (которые при этом еще по контракту и состояние потока оставляют во вполне определенном состоянии, а не "где сломалось"). Там же отсутствие поля — вполне ожидаемая ситуация. В крайнем случае, будут возвращать null/not null или какой-нибудь простенький Option с методом hasValue(). А вот IOException будет пробрасываться дальше. Как вы на кодах ошибок будете в данной ситуации действовать? Причем вам теперь нужно проверять, что именно там сломалось:
    errcode = readInt(...);
    if (errcode != BAD_FORMAT)
      return errcode;

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

    M>>Пожалуйста, приведите мой же пример (те же два уровня) с сохранением той же информации об ошибках — имени поля и имени структуры, где произошла ошибка.


    _>Да одно объявление классов этих исключений, с их полями и конструкторами, перекроет любые if'ы по объёму. Что касается "типов ошибок" в варианте с кодами возвратов, то даже так с ходу и не припомню видел ли я такое чудо вообще когда-нибудь. )))


    "Одно объявление классов ... с их полями и конструкторами" — это не свойство исключений. Это свойство поставленной вами задачи "выводить ошибки подробно". И большое количество классов следует из того, что классов ошибок на самом деле много и их нужно как-то описывать. Поэтому не важно, как именно вы это будете делать — исключениями, кодами ошибок или монадой со строго типизированными ошибками. Если убрать это требование, у меня будут исключения с одним/двумя конструкторами (делегирующим родителю) и вообще без полей, например. Т.е. проблема к исключениям отношения не имеет. Да, в Java record и discriminated union очень многословно руками записывают. Мне это надоело и при следующей необходимости discriminated union я их себе сделаю (на xtext + кодогенерация). В данном случае исключения — частный случай discriminated union (открытый или закрытый в зависимости от ситуации). Но, повторюсь, это не проблема исключений, это проблема описания обычных типов данных. Какой-нибудь struct для тех же случаев (вместе с инициализацией) будет ничуть не лучше (а то и хуже). А так как struct вернуть из метода еще и не так просто, то на "кодах возврата" подробная информация обычно как раз не делается. Банально не удобно и получается очень много кода.

    Да, еще одна проблема "на кодах возврата". Исключения, все-таки, представляют собой открытое легко расширяемое множество с некоторыми концепциями именования. Это с большой долей вероятносит гарантирует, что "двух одинаковых" исключений в никаких библиотеках не будет (именование пакетов вроде com.acme.product...). А вот набор кодов ошибок ограничен. Так что вполне вероятно, что две библиотеки будут иметь пересекающиеся диапазоны кодово ошибок с различной семантикой? Что вы будете делать в этом случае? Делать кучу оберток вокруг одной из библиотек, переводя ее коды в коды своего приложения? Будете вручную на каждый вызов переделывать кучи ошибок (почти предыдущий вариант, только обработка по месту вызова)? Или ничего не будете делать и предоставите пользователю возможность угадывать, что же на самом деле там сломалось с кодом ошибки 0x3211? Даже "исключения по-умолчанию" (без корректного оборачивания на нужных уровнях) придут с правильным описанием ошибки (правда, слишком низкоуровневым) и гадать нужно будет не так много.
    Re[33]: Это-то как раз просто решается...
    От: ambel-vlad Беларусь  
    Дата: 02.03.13 19:17
    Оценка:
    Здравствуйте, Erop, Вы писали:

    E>>>Если ты так или иначе работаешь в команде, то предлагаю тебе эксперимент.

    E>>>Объявляешь приз в 100 баксов за каждый выявленный в твоём коде случай нарушения базовой гарантии и башляешь до тех пор, пока не расстанешься с иллюзиями

    AV>>КО говорит, что неиспользование исключений не избавляет от этой проблемы. Посему спрашивается, к чему это было?


    E>Обсуждался довольно простой вопрос -- обеспечивается ли азовая гарантия В РЕАЛНОСТИ...

    E>Исключения тут правда не при чём. Просто если исключения летают редко, то становится сильно менее важно, обеспечивается базовая гарантия или нет

    С какой радости становится сильно менее важно?
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[55]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: ambel-vlad Беларусь  
    Дата: 03.03.13 03:21
    Оценка:
    Здравствуйте, Erop, Вы писали:

    I>>Да просто иногда под процедурным понимают императивное.

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

    То что он выглядит не сильно приятно не отменяет того, что это он переписан в процедурном подходе. Это раз. И покажи не ужас, когда ошибку можно обработать на 4-5 уровней выше нежели ее обнаружение? И чтобы два раза не переписывать, то добавим, что верхняя фунция внутри себя вызывает не одну функцию, а три-пять. И те внутри себя тоже вызывают что-то. И при обработке ошибок на верхнем уровне хотелось бы знать что за ошибка произошла и в какой именно функции. А чтобы еще более весело стало, то функции, в которых возникают ошибки пишутся другими командами. Посему их изменить ты не можешь. А коды ошибок они используют одинаковые.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[45]: Вот еще, или я, кажется, читать разучился
    От: ambel-vlad Беларусь  
    Дата: 03.03.13 04:02
    Оценка:
    Здравствуйте, alex_public, Вы писали:

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


    ОК.

    _>Но коду использующему функцию read_file совершенно ни к чему знать из-за какой конкретно ерунды файл не читается корректно.


    Возможно. Но не обязательно.

    _>Аналогично и коду использующему read_profile должно быть абсолютно пофиг какой конкретно из файлов не прочитался.


    А вот тут мимо. Код, который использует read_profile, знает как отработать ошибочную ситуацию. Как минимум что-то кинуть в лог. А то потом устанешь гадать, например, почему же не сохранились настройки с прошлого запуска.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[47]: Вот еще, или я, кажется, читать разучился
    От: ambel-vlad Беларусь  
    Дата: 03.03.13 04:02
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    _>Значит смотрим на твой же конкретный пример (стек вызовов: read_profile -> load_files -> load_file -> read_file -> read_header -> read_field_group -> read_named_field -> read_integer). Как я понимаю при автоматическом сценарии (это то, что ты вроде как пропагандируешь и то что я назвал немодульным говнокодом) у нас read_integer кидает исключение, а ловится оно где-то вокруг read_profile. Ну так в таком случае мы можем сказать пользователю только то, что "где-то вместо цифры встретила буква" и всё! Мы даже имя файла сообщить не сможем, т.к. ни read_integer, ни код вокруг read_profile его не знает. Не говоря уже о каких-то ещё деталях типа имени поля.


    Кто тебе сказал что не можем? Еще как можем. Исключения можно вкладывать друг в друга. А то при помощи кодов ошибок сообщить это гораздо сложнее.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[46]: Вот еще, или я, кажется, читать разучился
    От: ambel-vlad Беларусь  
    Дата: 03.03.13 05:13
    Оценка:
    Здравствуйте, jazzer, Вы писали:

    E>>IMHO, всё ровно наоборот.

    E>>1) Подумали ли о том, что будет, если провалится то или это мето или просто так взяли и написали "чисто и ясно" и расслабились, НЕ ВИДНО.
    J>Аналогично не видно, обработали ли код возврата или это просто функция возвращает void, или если обработали, то все ли возможные значения обработаны.

    Кстати, еще один момент. Разработчики вызываемой функции добавили новый код возврата. И забыли об этом обрадовать тех, кто использует ее. Да, раздолбайство. Да, этого не должно быть. Но это реальность. Что делать в кодом, который вызывает такую функцию? Добавлять еще один if на неизвестные коды? И так с каждым вызовом делать?
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[36]: Вот еще, или я, кажется, читать разучился
    От: ambel-vlad Беларусь  
    Дата: 03.03.13 06:03
    Оценка:
    Здравствуйте, andyp, Вы писали:

    A>Часто бывает так, что поймавший просто не знает что делать с ошибкой.


    А зачем он ловит исключение если не знает что с ним делать? Шоб було?

    A>Я часто всякую математику пишу. Есть "классная" мысль — кидать domain_error, если не попал в область определения функции (ну например корень из отрицательного числа пытаешься подсчитать). Так вот, не понятно, что с этим исключением делать на верхнем уровне после вызовов 100500 корней внизу.


    А почему оно не обрабатывается на более низких уровнях?

    A>В результате — УГ и отладка за автора.


    Заставь дурака молиться, то он и лоб расшибет. В данном случае смена инстумента (замена исключений на коды возврата) ничем не поможет. Скорее только ухудщит все.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[54]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: maxkar  
    Дата: 03.03.13 06:13
    Оценка:
    E>>Здравствуйте, jazzer, Вы писали:

    J>Э-э-э.... Надеюсь, не надо доказывать, что от статических переменных можно элементарно избавиться, передавая их всюду (как это делается в функциональных языках, там для этого даже спецсахар есть в виде монад)?


    Для анализа можно и не передавать, а разрешить возвращать что-то чуть более сложное, чем примитивные типы. Вместо обычного int везде возвращать Either Exception Int и т.п.. То, что оно откомпилируется в другой код, в данном случае не важно (он будет эквивалентен коду с проверками).

    И еще по поводу "можно". Не просто можно, а сделано на практике. Подробности здесь и далее по ссылке. Фактически там описана та самая монада (Either AbruptCompletion) и несколько "продвинутых" функций (try конвертирует одну монаду в другую). Функциональыне языки в этом месте очень сильно повлияли на java (не только монада, но и то, что у каждого statement есть "значение"). Что интересно, throw, break и continue являются частными случаями одного и того же AbruptCompletion. И во многих местах могут обрабатываться совершенно одинаково. Так что анализу определенных свойств программы исключения совершенно не мешают.
    Re[55]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: maxkar  
    Дата: 03.03.13 06:17
    Оценка:
    Здравствуйте, Erop, Вы писали:

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


    Придумали, придумали. В java есть. Типичная монада вроде бы. И доказывать свойства вроде definite assignment и некоторые другие соврешенно не мешает.

    При понимании модели легко позволяет описывать, что именно делают ужасы вроде
    for (i = 0; i < 10; i++) {
      try {
        return i;
      } finally {
        continue;
      }
    }
    Re[57]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: maxkar  
    Дата: 03.03.13 06:28
    Оценка:
    Здравствуйте, Erop, Вы писали:

    E>Окей, вот мы размножили все catch'и так, словно каждый оператор завёрнут в свой индивидуальный try{}catch, и даже смогли вычислить wp от постусловия программы для содержимого всех этих catch...

    E>Как теперь эту кучу предикатов склеить обратно в предикат для того catch, который мы пишем реально?..

    Так банально же... Для каждой строки предусловие "предыдущий фрагмент завершился успешно И некий предикат ИЛИ предыдущий фрагмент завершился с исключением А". И склеивается оно вполне нормально — "первый шаг завершился с ошибкой ИЛИ первый шаг завершился успешно И с предикатом И второй шаг завершился с ошибкой" и т.д.

    E>Суть же подхода Дейкстры состоит в том, что мы можем записать условие того, попадём мы в постусловие программы или нет для любого места в программе, и при этом условие не будет зависеть от пути, по которому мы в это место попали. Только от значений переменных и всё.


    А что мешает то? В catch мы попадаем, если есть ошибка. Задача catch — восстановить все варианты блока try{}catch{}. Если мы имеем некий формализм по описанию исключений, мы знаем, в какой строке выше какие исключения могут происходить. В чем проблема то? Если ошибки нет, мы в catch не попадем. Если ошибку не обработали, то мы вообще в весь остаток функции не попадем.

    E>Я понима, как получить из кода с исключениями эквивалентный на кодах возвратов и goto, так скажем, но он будет непроцедурный. Я понимаю, как введением очень массового размножения кода и массовы же return из середины функций, написать в каком-то смысле эквивалентный и процедурный, но этот эквивалентный и процедурный будет ОЧЕНЬ СЛОЖНЫМ. И не понятно как его свернуть обратно в относительно простой. То есть как по предикатам этого "эквивалентнго" кода восстановать аналогичные предикаты для исходного?


    Кстати, а вы допускаете return в середине функции? Без него некоторые программы читаются гораздо хуже (глубокая вложенность из if'ов читается тяжеловато). А с ними возникают все те же проблемы — как объединять все предикаты из разных return на выходе из программы (например, чтобы проверить очистку ресурсов).
    Re[59]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: maxkar  
    Дата: 03.03.13 06:44
    Оценка:
    Здравствуйте, Erop, Вы писали:

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


    А зачем так делать? Откуда там произвольные исключения? Можно ведь взять checked exceptions, например, и ограничить их спектр. Так что проблем не будет. То, что c++ не использует checked exception, это его проблемы. К тому же для доказательства свойств можно и какой-то свой аналог их ввести (описывать в документации, проверять теми же контрактами и т.п.). Все равно контракты обычно проверяются самими программмистами (а в большинстве случаев контракты вообще отсутствуют, так как программисты не любят писать документацию).

    E>Собственно этот вот переход от явно перечисленных мест/причин провалу к открытому множеству того и другого и делает программу малопонятной и труднодоказуемой, если вообще доказуемой.


    Забудьте вы про доказуемость. Дейкстра свой труд писал давным давно, тогда многое было по-другому. Его утверждения про доказуемость применимы в первую очередь к неполиморфным участкам кода. Как только появляется полиморфмизм, все доказательства и контракты усложняются. Если полиморфизм открытый (пользователь может создать еще наследников классов или передать что-то свое в библиотеку), ситуация еще более усложняется.

    И еще. Я очень плохо представляю, как можно доказывать базовые гарантии обработки ошибок в реальной жизни. Проблема очень простая. Пусть что-то у нас сломалось, мы решили очистить ресурсы и вернуть код ошибки. Вопрос: как доказать, что мы не поймаем переполнение стека в процессе очистки уже выделенных ресурсов? Как вы будете это доказывать в условиях полиморфизма? При этом все нужно доказывать в каком-то обобщенном виде, ведь мы могли уже считать к этому моменту XML DOM неизвестной глубины и теперь будем его очищать. Какие контракты будут на пользовательские классы и т.п., чтобы гарантировать желательное поведение "по очистке", если пользовательский класс инициализировался (создался фабрикой, например)?

    Кстати, что там будет с переполнением стека в C++? На той же java я его могу поймать и обработать. Да, это нужно далеко не везде, но все же может быть нужно. Например, я запускаю какой-нибудь рекурсивный поисковой алгоритм в отдельном потоке. Если алгоритм прошел, хорошо. Если не прошел (не хватило стека), я запускаю другой алгоритм (более медленный/с худшими результатами) и получаю результат от него. Можно делать подобное в процедурном стиле? И как вы будете в этом случае доказывать, что "стека на очистку данных хватит даже если где-то в середине вычисления стека для того шага не хватило"?
    Re[34]: Это-то как раз просто решается...
    От: Erop Россия  
    Дата: 03.03.13 07:16
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:


    E>>Обсуждался довольно простой вопрос -- обеспечивается ли базовая гарантия В РЕАЛНОСТИ...

    E>>Исключения тут правда не при чём. Просто если исключения летают редко, то становится сильно менее важно, обеспечивается базовая гарантия или нет

    AV>С какой радости становится сильно менее важно?

    С такой, что нам всё равно, что будет в случае исключения, которого не будет...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[56]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 03.03.13 07:26
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

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


    Во-первых, ты смешиваешь несколько разных, независимых обстоятельств.
    1) Что красивее
    2) Что дороже
    3) Что надёжнее

    Собственно (1) я вообще не обсуждаю
    Что касается (2) и (3), то использование всяких отмотчиков стеков RAII и т. д. в целом повышает надёжность кода на тему утечек. Правда совсем уж гарантий от них не даёт. Но какой-то уровень таки даёт, то есть в целом для среднего кода повышает его надёжность, повышает стоимость написания, но, возможно, снижает стоимость поддержки.
    Использование исклчений понижает надёжность кода, повышает стоимость поддержки, и, возможно и стоимость разработки.
    Чтобы компенсировать негатив от внедрения исклбчений приходится вводить соглашения, вроде базовой гарантии при исключениях, которая снова повышает надёжность, ещё раз повышает стоимость разработки, но, нозможно снижает стоимость поддержки, если она реально дастигнута, о всяком случае...

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

    Ну там, готовы ли мы, что иногда будем падать? То есть какое падение в надёжность от перехода "RAII+исключения по исключительным случам" -> "исключения на каждый чих" мы можем себе позволить, и какую часть этого падения НА ПРАКТИКЕ удастся скомпенсровать введением базовой гарантии, хотя бы частичным.

    Вот по моему опыту переноса больших программ, могу сказать, что течь базовой гарантии была третьим источником трудноотлаживаемых багов после багов/отличий коспиляторов и порядка инициализации и вообще работы статических переменных...
    Что как бы намекает
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[35]: Это-то как раз просто решается...
    От: ambel-vlad Беларусь  
    Дата: 03.03.13 07:26
    Оценка:
    Здравствуйте, Erop, Вы писали:

    E>>>Обсуждался довольно простой вопрос -- обеспечивается ли базовая гарантия В РЕАЛНОСТИ...

    E>>>Исключения тут правда не при чём. Просто если исключения летают редко, то становится сильно менее важно, обеспечивается базовая гарантия или нет

    AV>>С какой радости становится сильно менее важно?

    E>С такой, что нам всё равно, что будет в случае исключения, которого не будет...

    Зато нам не все равно что будет в случае ошибки. Проблем никуда не делась.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[36]: Это-то как раз просто решается...
    От: niXman Ниоткуда https://github.com/niXman
    Дата: 03.03.13 07:31
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

    E>С такой, что нам всё равно, что будет в случае исключения, которого не будет...


    хочу заметить, что во всех тредах про исключения vs коды ошибок, Егор рассуждает о вакуумных конях, придумывает несуществующие проблемы которые с успехом сам и решает, и просто словоблудит =)
    alex_public и еще кот-то, вообще приводили примеры, где исключения использовались для возврата значений.
    просто мое наблюдение. сплошной фейспалм.
    пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
    Re[57]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: ambel-vlad Беларусь  
    Дата: 03.03.13 07:47
    Оценка:
    Здравствуйте, Erop, Вы писали:

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


    E>Во-первых, ты смешиваешь несколько разных, независимых обстоятельств.

    E>1) Что красивее
    E>2) Что дороже
    E>3) Что надёжнее

    E>Собственно (1) я вообще не обсуждаю


    Разве? "УГ код" — это не красивость разве*

    E>Что касается (2) и (3), то использование всяких отмотчиков стеков RAII и т. д. в целом повышает надёжность кода на тему утечек. Правда совсем уж гарантий от них не даёт. Но какой-то уровень таки даёт, то есть в целом для среднего кода повышает его надёжность, повышает стоимость написания, но, возможно, снижает стоимость поддержки.

    E>Использование исклчений понижает надёжность кода, повышает стоимость поддержки, и, возможно и стоимость разработки.

    Это еще требует доказательств.

    E>Чтобы компенсировать негатив от внедрения исклбчений приходится вводить соглашения, вроде базовой гарантии при исключениях,


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

    E>ещё раз повышает стоимость разработки,


    повышает по сравнению с чем?

    E>Я думаю, что ты со всем этим согласен, и весь вопрос в балансе этих вкладов.


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

    E>Ну там, готовы ли мы, что иногда будем падать?


    Это не проблема исключений.

    E>То есть какое падение в надёжность от перехода "RAII+исключения по исключительным случам" -> "исключения на каждый чих"


    А не надо "исключение на каждый чих". С дуру сам знаешь что можно сломать.

    E>Вот по моему опыту переноса больших программ, могу сказать, что течь базовой гарантии была третьим источником трудноотлаживаемых багов после багов/отличий коспиляторов и порядка инициализации и вообще работы статических переменных...

    E>Что как бы намекает

    А при переносе программ с кодами ошибок таких багов не было?

    Кстати, так что с примером кода?
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[58]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 03.03.13 07:57
    Оценка:
    Здравствуйте, maxkar, Вы писали:

    M>Так банально же... Для каждой строки предусловие "предыдущий фрагмент завершился успешно И некий предикат ИЛИ предыдущий фрагмент завершился с исключением А". И склеивается оно вполне нормально — "первый шаг завершился с ошибкой ИЛИ первый шаг завершился успешно И с предикатом И второй шаг завершился с ошибкой" и т.д.


    M>А что мешает то? В catch мы попадаем, если есть ошибка. Задача catch — восстановить все варианты блока try{}catch{}. Если мы имеем некий формализм по описанию исключений, мы знаем, в какой строке выше какие исключения могут происходить. В чем проблема то? Если ошибки нет, мы в catch не попадем. Если ошибку не обработали, то мы вообще в весь остаток функции не попадем.


    Проблема в структуре получающихся предикатов.
    Их либо вообще не получается написать, либо получается, что всё зависит от всего.
    Ну то есть в НОРМАЛЬНОЙ программе кроме того, что у нас будет функция, read_profile, которая спрячем внутри себя подробноти как там и откуда итается профиль, за одно и предусловие этой функции свернётся в "профиль доступен", А в программе которая написана, так что у нас стек вызовов глубиной а пять функций. шириной в 10 и наружу торчат 100500 исключений, то там получится предусловие вида " на таком-то смещее в таком-то файле стоиит цифра, а не буква" и так 100500 раз...
    Собственно полезная логика в этом шуме просто утонет бесследно и всё. А так пролем никаких нет

    Кроме той проблемы, что нет и смысла.
    В принципе ждя многих лапшеобразных программ тоже можно наделать всяких хитрых преобразований и допущений и таки написать какие-то пред/пост-условия, только их структура тоже будет плохой и мало поможет в написании и подержке программы...

    Это и говорит нам о том, что подход не работает...


    M>Кстати, а вы допускаете return в середине функции? Без него некоторые программы читаются гораздо хуже (глубокая вложенность из if'ов читается тяжеловато). А с ними возникают все те же проблемы — как объединять все предикаты из разных return на выходе из программы (например, чтобы проверить очистку ресурсов).


    Ну без фанатизма если, то допускаю...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[60]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 03.03.13 08:21
    Оценка:
    Здравствуйте, maxkar, Вы писали:

    M>А зачем так делать? Откуда там произвольные исключения? Можно ведь взять checked exceptions, например, и ограничить их спектр. Так что проблем не будет. То, что c++ не использует checked exception, это его проблемы.


    Ну мы же обсуждаем РЕАЛЬНЫЕ практики, а не гипотетические?..
    И с самого начала эта тема была в С++/С, так что плюсовые к тому же.
    В той же Яве всё-таки есть GC, что очень упрощает жизнь программам с исключениями.
    Гарантии безопасности проще намного выглядят и обеспечить их тоже проще...

    M>(а в большинстве случаев контракты вообще отсутствуют, так как программисты не любят писать документацию).

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

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


    M>Забудьте вы про доказуемость. Дейкстра свой труд писал давным давно, тогда многое было по-другому. Его утверждения про доказуемость применимы в первую очередь к неполиморфным участкам кода. Как только появляется полиморфмизм, все доказательства и контракты усложняются. Если полиморфизм открытый (пользователь может создать еще наследников классов или передать что-то свое в библиотеку), ситуация еще более усложняется.


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

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

    Не очень понятно, что такое "какая-нибудь ошибка"?..
    Если это ожидаемое поведение, ну там грузили что-то грузили и так и не загрузили, то это как бы просто постусловие просто функции. Обычными методами всё разрулится. Если в языке есть GC, то просто 0 можно из функции вернуть, а дальше пусть GC парится. Если нет, то разрушим, так же, обычно. Или достроим, а потом разрушим. В общем не понятно чем эта ситуация отличается от разных других ситуаций...

    M>Вопрос: как доказать, что мы не поймаем переполнение стека в процессе очистки уже выделенных ресурсов?


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

    M>Кстати, что там будет с переполнением стека в C++? На той же java я его могу поймать и обработать. Да, это нужно далеко не везде, но все же может быть нужно. Например, я запускаю какой-нибудь рекурсивный поисковой алгоритм в отдельном потоке. Если алгоритм прошел, хорошо. Если не прошел (не хватило стека), я запускаю другой алгоритм (более медленный/с худшими результатами) и получаю результат от него. Можно делать подобное в процедурном стиле? И как вы будете в этом случае доказывать, что "стека на очистку данных хватит даже если где-то в середине вычисления стека для того шага не хватило"?


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

    Можно пример алгоритма, о котором речь, кстати?
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[56]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 03.03.13 09:23
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

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


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

    То есть тут во джассер про еррор-проне код писал там и т. п.
    Так тут получилось смешение двух РАЗНЫХ подходов и смешение аргументаций за тот и за другой...
    Идея про еррор-проне состоит в том, что надо паисать программы так, что бы писать правильные программы было удобнее, чем неправильные.
    И один из подходов на эту тему состоит в том, что бы программа максимально бысро "выламывалась", а не продолжала делать что-то не понятное, пока не упрётся в совсем какое-то непреодолимое противоречие, вроде перехода по невалидному адресу и т. п.

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

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

    AV>А чтобы еще более весело стало, то функции, в которых возникают ошибки пишутся другими командами. Посему их изменить ты не можешь. А коды ошибок они используют одинаковые.


    Для сравнения предлагаю рассмотреть случай, когда функции пишутся разными командами и с разными подходами, но с исключениями
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[36]: Это-то как раз просто решается...
    От: Erop Россия  
    Дата: 03.03.13 09:28
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

    AV>Зато нам не все равно что будет в случае ошибки. Проблем никуда не делась.


    Тут есть некоторая терминологическая путанница.
    "ошибка" -- это что? То, что входит в ТЗ, грубо говоря, или то, чего мы не ждём и обрабатывать не планируем.

    Если первое, то это надо покрывать тестами, поддерживать в коде и т. д.
    Если второе, то нам пофигу что будет, когда случится то, чего быть не должно...
    Вернее не пофигу, а ообычно надо минимализировать вероятность наступения того, чего быть не должно. а не улучшать поведение программы в этом маловероятном сценарии
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[57]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: ambel-vlad Беларусь  
    Дата: 03.03.13 09:36
    Оценка:
    Здравствуйте, Erop, Вы писали:

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


    E>Ну, как бы, в нормальных программах принято скрывать подробности реализации от клиентского кода.


    вот у тебя обломилось получение байти из сокета. Как ты собираешься это обрабатывать в функции чтения данных из сокета?


    E>То есть тут во джассер про еррор-проне код писал там и т. п.


    Ты не на других переводи стрелки, а покажи пример кода.

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


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

    E>А есть другой подход, типа у нас всё ходит, мы всё написали, а если что-то не так, кидаем исключение и надеемся, что всё срастётся где-то выше по стеку.


    Исключение — это не только их бросание, но и обработка. Иначе зачем их бросать.

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


    Слишком много приходится думать. И поэтому рано или поздно забудешь подумать.

    E>А в случае исклбчений можем подумать, а можем и не подумать, в целом-то наши раздумия никаких следов в кое не отсавляют


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

    AV>>А чтобы еще более весело стало, то функции, в которых возникают ошибки пишутся другими командами. Посему их изменить ты не можешь. А коды ошибок они используют одинаковые.


    E>Для сравнения предлагаю рассмотреть случай, когда функции пишутся разными командами и с разными подходами, но с исключениями


    Ты сначала приведи свой код с кодами ошибок. Кстати, про разные подходы ты добавил от себя. Не хочешь примерить это уточнение к коду, который ты приведешь?
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[37]: Это-то как раз просто решается...
    От: ambel-vlad Беларусь  
    Дата: 03.03.13 09:39
    Оценка:
    Здравствуйте, Erop, Вы писали:

    AV>>Зато нам не все равно что будет в случае ошибки. Проблем никуда не делась.


    E>Тут есть некоторая терминологическая путанница.

    E>"ошибка" -- это что? То, что входит в ТЗ, грубо говоря, или то, чего мы не ждём и обрабатывать не планируем.

    То что ты в месте возникновения не знаешь как обработать. А обработать можешь в другом месте.


    В случае исключений ты требуешь соблюдения инварианта, а в случае кодов ошибок это святой дух обеспечивает?
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[58]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 03.03.13 09:47
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

    AV>Разве? "УГ код" — это не красивость разве*

    Это дороговизна поддержки. О вкусах вообще спорить мало смысла

    E>>Использование исклчений понижает надёжность кода, повышает стоимость поддержки, и, возможно и стоимость разработки.


    AV>Это еще требует доказательств.

    А что из тёх вызывает сомнения? Если в среднюю прогу на С вклячить исключения, случиться клиьма 146%.
    Так что для обеспечения просто работоспособности, а не то что бы надёжности, надо таки проводить какие-то ДОПОЛНТЕЛЬНЫЕ мероприятия, в которых ещё и ошибиться можно...

    AV>отказываясь от исключений, проблему ты оставляешь. Просто она лишь немного изменяет вид.


    Какую конкретно проблему?..

    AV>Я из исключений не делал серебряной пули. За все надо платить. Но цена кодов возвратов в целом в большинстве случаев получается выше.


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

    AV>А не надо "исключение на каждый чих". С дуру сам знаешь что можно сломать.

    Ну так это же и обсужается, можно ли исключения кидать часто, или таки если мы уж кинули исклбчения, то это примерно как провал assert'а по степени ожидаеммости...

    AV>А при переносе программ с кодами ошибок таких багов не было?

    Ну ошибки есть всегда. Но обычно есть ТЗ, тесты, логи...
    А с исключениями обычно ничего нет, все надеются, что всё будет "само"...
    В принципе я их понимаю, что если на "само" не рассчитывать то с исключениями выходят СЛОЖНЕЕ, чем с условными кодами возврата...

    AV>Кстати, так что с примером кода?


    С примером кода чего конкртено?
    Я тут в этих двух темах приводил уже кучу примеров разного кода...
    Мне тут всё собщают, что типа это всё кони в вакууме...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[59]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: ambel-vlad Беларусь  
    Дата: 03.03.13 10:09
    Оценка:
    Здравствуйте, Erop, Вы писали:

    AV>>Разве? "УГ код" — это не красивость разве*

    E>Это дороговизна поддержки. О вкусах вообще спорить мало смысла

    А там не был код для работы человека с ним. Там код был для других целей.

    E>>>Использование исклчений понижает надёжность кода, повышает стоимость поддержки, и, возможно и стоимость разработки.


    AV>>Это еще требует доказательств.

    E>А что из тёх вызывает сомнения?

    Все три.

    E>Если в среднюю прогу на С вклячить исключения, случиться клиьма 146%.


    Если их только выбрасывать, то так и будет.

    E>Так что для обеспечения просто работоспособности, а не то что бы надёжности, надо таки проводить какие-то ДОПОЛНТЕЛЬНЫЕ мероприятия, в которых ещё и ошибиться можно...


    Какие дополнительные мероприятие необходимо проводить?

    AV>>отказываясь от исключений, проблему ты оставляешь. Просто она лишь немного изменяет вид.


    E>Какую конкретно проблему?..


    Сохранения инварианта

    AV>>Я из исключений не делал серебряной пули. За все надо платить. Но цена кодов возвратов в целом в большинстве случаев получается выше.


    E>Ну вот мы и пришли к тому же, к сравнению стоимостей тех или иных подходов...


    От этого и не уходили.

    AV>>А не надо "исключение на каждый чих". С дуру сам знаешь что можно сломать.

    E>Ну так это же и обсужается, можно ли исключения кидать часто,

    Что есть "чих"?

    E>или таки если мы уж кинули исклбчения, то это примерно как провал assert'а по степени ожидаеммости...


    Облом с чтением байта их сокета такой случай?

    AV>>А при переносе программ с кодами ошибок таких багов не было?

    E>Ну ошибки есть всегда. Но обычно есть ТЗ, тесты, логи...
    E>А с исключениями обычно ничего нет, все надеются, что всё будет "само"...

    Чего-чего? Ты беленой объелся? Если ты в качестве плохого кода с исключениями приводишь какое-то откровенное дерьмо, то я такого же дерься навидался и с кодами возвратов. Развесистый макаронокод с несколькими десятками ифов в одной функции. Причем, как и ожидалось, кучу кодов ошибок забывали проверить. А потом когда возникала ошибка, то ломали голову. Потому что не могли найти ошибку.

    AV>>Кстати, так что с примером кода?


    E>С примером кода чего конкртено?


    О котором я писал чуть выше. Совсем рядом тут.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[44]: Вот еще, или я, кажется, читать разучился
    От: Tanker  
    Дата: 03.03.13 10:38
    Оценка:
    Здравствуйте, Erop, Вы писали:

    T>>Принципиальной разницы нет, и то и другое это исключения.


    E>Тебе кажется, что возможность не разматывать стек непринципиальна?


    Это детали реализации. Главное что твой вариант это тоже исключения и код обработки находит в одном месте.
    The animals went in two by two, hurrah, hurrah...
    Re[58]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 03.03.13 11:31
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

    AV>вот у тебя обломилось получение байти из сокета. Как ты собираешься это обрабатывать в функции чтения данных из сокета?


    Вернёшь ошибку, тот, кто позвал -- разберётся...
    Если так удобнее вызывающей стороне, то можно представить вызывающей сотроне версию функции read_byte, которая падает при обломе по assert там или по имключению... не суть.

    AV>Забытая проверка кода ошибки скорее приведет к второму подходу. Когда остается только гадать что же в действительности произошло.


    Так на это есть тестирование и меры, по обеспечению его полноты...

    AV>Исключение — это не только их бросание, но и обработка. Иначе зачем их бросать.

    Ну ясен пень обработка где-то какая-то будет. Вопрос лишь в том удачная ли

    AV>Слишком много приходится думать. И поэтому рано или поздно забудешь подумать.

    Ну так ведь и при программировании всё время думать приходится...

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

    AV>Можем не подумать. Только это, как правило, быстрее обнаружится.

    Почему? Пиши aasert'ы так, что бы программа ыстро выламывалась и всё обнаружится быстро что так что этак...

    AV>Ты сначала приведи свой код с кодами ошибок. Кстати, про разные подходы ты добавил от себя. Не хочешь примерить это уточнение к коду, который ты приведешь?


    Ну это любой обычный код так выглядит. Скажем никогда не видел std::cout и сервисы из stdio в одной программе?

    Я уже приводил примеры кода. Но их тут обозвали абстрактными...

    Ну я так понимаю, что всё программистское сообщество сломало себе зубы на задачке написать типа парсер файла профайла без использования исключений и при этом хорошо и понятно?

    Ну типа будет какой-то класс CConfigParser, на вход которого (например в конструктор ) будут передавать текст конфигурационника, или какой-то аналог, скажем открытый поток.

    CConfigParser будет иметь какой-то интерфейс, типа там считать следующую секцию, проитерировать ключи в секции и т. д.

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

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

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

    Что конкртено из этого ты хотел бы, что бы я написал?..
    Ну, в смысле, что конкретно ты сам не знаешь, как обычно пишут?..
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[38]: Это-то как раз просто решается...
    От: Erop Россия  
    Дата: 03.03.13 11:33
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

    AV>В случае исключений ты требуешь соблюдения инварианта, а в случае кодов ошибок это святой дух обеспечивает?


    Ну это же просто код будет, без вылета любоо исключения из любого места? То есть надо просто к моменту return что бы всё было корректно...

    Ты приведи пример функции, где это трудно обеспечить, может я просто не понимаю о чём речь?
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[45]: Вот еще, или я, кажется, читать разучился
    От: Erop Россия  
    Дата: 03.03.13 11:37
    Оценка:
    Здравствуйте, Tanker, Вы писали:

    E>>Тебе кажется, что возможность не разматывать стек непринципиальна?


    T>Это детали реализации. Главное что твой вариант это тоже исключения и код обработки находит в одном месте.


    Ха, так в этих-то деталях весь дьявол-то и сидит
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[39]: Это-то как раз просто решается...
    От: ambel-vlad Беларусь  
    Дата: 03.03.13 11:50
    Оценка:
    Здравствуйте, Erop, Вы писали:

    AV>>В случае исключений ты требуешь соблюдения инварианта, а в случае кодов ошибок это святой дух обеспечивает?


    E>Ну это же просто код будет, без вылета любоо исключения из любого места?


    Да.

    E>То есть надо просто к моменту return что бы всё было корректно...


    да, чтобы к моменту return все было корректно. Как ты это собираешься обеспечивать в случае кодов ошибок?
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[59]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: ambel-vlad Беларусь  
    Дата: 03.03.13 11:55
    Оценка:
    Здравствуйте, Erop, Вы писали:

    AV>>вот у тебя обломилось получение байти из сокета. Как ты собираешься это обрабатывать в функции чтения данных из сокета?


    E>Вернёшь ошибку, тот, кто позвал -- разберётся...


    А тот кто позвал тоже не знает что делать с этой ошибкой. Кидаем код ошибки еще выше?

    AV>>Забытая проверка кода ошибки скорее приведет к второму подходу. Когда остается только гадать что же в действительности произошло.


    E>Так на это есть тестирование и меры, по обеспечению его полноты...


    Простой пример. Была функция. Не тобой написанная. Но ты ее юзаешь. Написал тесты. Все хорошо. Потом пришла новая версия этой функции. С новым кодом. О котором ты не знал или забыл. Как твои старые тесты это отловят?

    AV>>Исключение — это не только их бросание, но и обработка. Иначе зачем их бросать.

    E>Ну ясен пень обработка где-то какая-то будет. Вопрос лишь в том удачная ли

    А почему она будет удачная в случае кодов ошибок и будет неудачная в случае исключений? Может дело не в инструменте, а в голове?

    AV>>Слишком много приходится думать. И поэтому рано или поздно забудешь подумать.

    E>Ну так ведь и при программировании всё время думать приходится...

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

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


    Каким образом?

    AV>>Можем не подумать. Только это, как правило, быстрее обнаружится.

    E>Почему? Пиши aasert'ы так, что бы программа ыстро выламывалась и всё обнаружится быстро что так что этак...

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

    AV>>Ты сначала приведи свой код с кодами ошибок. Кстати, про разные подходы ты добавил от себя. Не хочешь примерить это уточнение к коду, который ты приведешь?


    E>Ну это любой обычный код так выглядит. Скажем никогда не видел std::cout и сервисы из stdio в одной программе?


    Видел. И не такое видел. И что?

    E>Я уже приводил примеры кода. Но их тут обозвали абстрактными...


    Я просил более чем конкретный код. И пишется он не так уж и долго. Но на протяжении нескольких сообщений это вызывает затруднения у тебя. Или какая-то другая причина не дает тебе это сделать?
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[50]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 03.03.13 13:28
    Оценка:
    Здравствуйте, maxkar, Вы писали:

    M>Так вы же сами просили "ошибки подробно" описывать. И говорили, что на кодах ошибок это проще, чем на исключениях . И я в предыдущем сообщении показывал, как это будет "по-умолчанию" с тремя уровнями исключений (без дополнительной обертки в readFieldGroup и т.п.). Завернуть все в unchecked и отлавливать на верхнем уровне тоже можно, но во вполне конкретных случаях и понимая, зачем и что с этим делать. Я за проработку обработки ошибок на ранних стадиях. Поэтому переоборачивание ошибок на границах слоев абстрации для меня — действие по умолчанию. Все исключения методов должны быть только в терминах интерфейса. Поэтому абстрактный ProfileService не может принципиально выбрасывать IOException. ProfileException — может. ProfileNotFound — может. А вот IOException — никогда.


    Нет, подробно описывать ошибки предложил как раз jazzer. Я же предпочитаю стараться строить архитектуру так, что бы вызовы сводились возвращению true/false, т.к. в большинстве случаев пользователю не нужны никакие технические подробности. Они нужны скорее разработчикам для отлова ошибок, но это полезнее реализовывать совсем другими методами (из области АОП), а не пронизывать ими основную логику.

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

    M>Не будет. jazzer правильный пример привел. Для опциональных полей будут опциональные обертки (которые при этом еще по контракту и состояние потока оставляют во вполне определенном состоянии, а не "где сломалось"). Там же отсутствие поля — вполне ожидаемая ситуация. В крайнем случае, будут возвращать null/not null или какой-нибудь простенький Option с методом hasValue(). А вот IOException будет пробрасываться дальше. Как вы на кодах ошибок будете в данной ситуации действовать? Причем вам теперь нужно проверять, что именно там сломалось:

    M>
    M>errcode = readInt(...);
    M>if (errcode != BAD_FORMAT)
    M>  return errcode;
    M>

    M>И если вдруг поломок будет более одной, все будет еще сложнее (несколько проверок после каждой функции). Если же вы каким-то другим способом предложите переписать код "с использованием кодов ошибок", я подобное же преобразование сделаю и для java, заменив только коды ошибок исключениями.

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

    M>"Одно объявление классов ... с их полями и конструкторами" — это не свойство исключений. Это свойство поставленной вами задачи "выводить ошибки подробно". И большое количество классов следует из того, что классов ошибок на самом деле много и их нужно как-то описывать. Поэтому не важно, как именно вы это будете делать — исключениями, кодами ошибок или монадой со строго типизированными ошибками. Если убрать это требование, у меня будут исключения с одним/двумя конструкторами (делегирующим родителю) и вообще без полей, например. Т.е. проблема к исключениям отношения не имеет. Да, в Java record и discriminated union очень многословно руками записывают. Мне это надоело и при следующей необходимости discriminated union я их себе сделаю (на xtext + кодогенерация). В данном случае исключения — частный случай discriminated union (открытый или закрытый в зависимости от ситуации). Но, повторюсь, это не проблема исключений, это проблема описания обычных типов данных. Какой-нибудь struct для тех же случаев (вместе с инициализацией) будет ничуть не лучше (а то и хуже). А так как struct вернуть из метода еще и не так просто, то на "кодах возврата" подробная информация обычно как раз не делается. Банально не удобно и получается очень много кода.


    Отдельно замечу что примеры из Java не совсем корректны в теме о пользе C++ исключений, т.к. в Java у исключений есть одно небольшое преимущество. А именно, там весь низкоуровневый api изначально кидает исключения. В то время как в случае C++ на низшем уровне мы обычно имеем дело с вызовами OS api или чем-то подобным, но в любом случае работающем через коды возврата. Т.е. возвращаясь к теме, если в Java код на самом низшем уровне будет выглядеть как "DoSomething();" и это уже будет кидать исключения (а для кодов возврата надо ещё постараться), то в C++ и коды возврата и исключения выглядят на этом уровне наравне: "if(!DoSomething()) return false;" или "if(!DoSomething()) throw MyException();".

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

    И так на мой взгляд ошибки возникающие в приложениях лучше всего обрабатывать с помощью исключений. При условие что под ошибкой подразумевается ситуация требующая прерывания исполнения приложения (ну или потока). Преимущества исключений тут в автоматической глубокой раскрутке стека. Причём в C++ тут преимуществ даже больше чем у Java за счёт RAII.

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

    M>Да, еще одна проблема "на кодах возврата". Исключения, все-таки, представляют собой открытое легко расширяемое множество с некоторыми концепциями именования. Это с большой долей вероятносит гарантирует, что "двух одинаковых" исключений в никаких библиотеках не будет (именование пакетов вроде com.acme.product...). А вот набор кодов ошибок ограничен. Так что вполне вероятно, что две библиотеки будут иметь пересекающиеся диапазоны кодово ошибок с различной семантикой? Что вы будете делать в этом случае? Делать кучу оберток вокруг одной из библиотек, переводя ее коды в коды своего приложения? Будете вручную на каждый вызов переделывать кучи ошибок (почти предыдущий вариант, только обработка по месту вызова)? Или ничего не будете делать и предоставите пользователю возможность угадывать, что же на самом деле там сломалось с кодом ошибки 0x3211? Даже "исключения по-умолчанию" (без корректного оборачивания на нужных уровнях) придут с правильным описанием ошибки (правда, слишком низкоуровневым) и гадать нужно будет не так много.


    Эээ ну это то как раз вообще не проблема. Причём ни при кодах возврата, ни при вашей схеме работы с исключениями. У нас же всё обрабатывается локально (на предыдущем уровне, а не где-то далеко назад по стеку) и соответственно код всегда знает контекст ошибки.
    Re[56]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: alex_public  
    Дата: 03.03.13 13:32
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

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


    Это же уже обсуждалось прямо в этой теме. Вы предлагаете Егору написать говнокод на кодах возврата и показать на нём что аналогичный говнокод на исключениях будет проще. Очень сомнительная идея.
    Re[48]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 03.03.13 13:37
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

    AV>Кто тебе сказал что не можем? Еще как можем. Исключения можно вкладывать друг в друга. А то при помощи кодов ошибок сообщить это гораздо сложнее.


    Естественно можно вкладывать но тогда соответствующие try/catch/throw расползаются по стеку вызова ничуть не слабее тех самых пробросов кодов возврата. И соответственно такой код начинает требовать больших (не забываем про классы исключений и т.п.) усилий, чем код с кодами возврата.

    P.S. Это всё уже обсуждалось прямо в этой темке — читайте что ли в начале все её подветки, а то лень повторяться. )
    Re[40]: Это-то как раз просто решается...
    От: Erop Россия  
    Дата: 03.03.13 20:19
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

    AV>да, чтобы к моменту return все было корректно. Как ты это собираешься обеспечивать в случае кодов ошибок?


    Ну так же, как и остальные постусловия. ВОт как ты, например, собираешься обеспечивать отсортированность массива к концу функции sort?

    Программирование там, тестирование модульное и функциональное и т. д...
    Кодирование, короче, типа
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[41]: Это-то как раз просто решается...
    От: ambel-vlad Беларусь  
    Дата: 03.03.13 21:09
    Оценка:
    Здравствуйте, Erop, Вы писали:

    AV>>да, чтобы к моменту return все было корректно. Как ты это собираешься обеспечивать в случае кодов ошибок?


    E>Ну так же, как и остальные постусловия.


    То есть в случае ошибки ты будешь либо откатывать проделанное назад либо получить новый инвариант. Так?


    E>Программирование там, тестирование модульное и функциональное и т. д...

    E>Кодирование, короче, типа

    Это все отменяется при исключениях? Нет, не отменяется.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[57]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: ambel-vlad Беларусь  
    Дата: 03.03.13 21:09
    Оценка:
    Здравствуйте, alex_public, Вы писали:

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


    _>Это же уже обсуждалось прямо в этой теме. Вы предлагаете Егору написать говнокод на кодах возврата и показать на нём что аналогичный говнокод на исключениях будет проще. Очень сомнительная идея.


    Предложи как обрабатывать ошибку чтения байти из сокета. В месте возникновения ты не знаешь является это ошибкой или нет. А знаешь лишь несколькими уровнями выше.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[49]: Вот еще, или я, кажется, читать разучился
    От: ambel-vlad Беларусь  
    Дата: 03.03.13 21:09
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    AV>>Кто тебе сказал что не можем? Еще как можем. Исключения можно вкладывать друг в друга. А то при помощи кодов ошибок сообщить это гораздо сложнее.


    _>Естественно можно вкладывать но тогда соответствующие try/catch/throw расползаются по стеку вызова ничуть не слабее тех самых пробросов кодов возврата.


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

    _>И соответственно такой код начинает требовать больших (не забываем про классы исключений и т.п.) усилий, чем код с кодами возврата.


    try/catch использовать как if/else, то усилий будет больше. Никто не отрицает этого. Если бензопилу использовать как обычную ножовку, то тоже моментально проклянешь ее.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[50]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 04.03.13 02:49
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

    AV>Гораздо меньше. Просто не надо каждый вызов функции обрамлять try/catch. Если не знаешь что делать с исключением и ничего полезного не можешь добавить, то не лови его.


    Определение классов исключений тоже забывать не надо. )

    AV>try/catch использовать как if/else, то усилий будет больше. Никто не отрицает этого. Если бензопилу использовать как обычную ножовку, то тоже моментально проклянешь ее.


    Ну собственно о широте области правильного применения мы тут и спорим. Вряд ли тут есть сторонники полного запрета исключений или сторонники всё всё делать через исключения.
    Re[58]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: alex_public  
    Дата: 04.03.13 02:51
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

    AV>Предложи как обрабатывать ошибку чтения байти из сокета. В месте возникновения ты не знаешь является это ошибкой или нет. А знаешь лишь несколькими уровнями выше.


    Как это не знаем? На уровне приложения мы всегда знаем должно ли оно завершаться в подобном случае (кстати довольно редкий сценарий по идее). Другое дело если мы пишем библиотеку — тут логичнее предусмотреть оба возможных варианта. Как собственно и сделано в Boost'е.
    Re[59]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: ambel-vlad Беларусь  
    Дата: 04.03.13 03:02
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    AV>>Предложи как обрабатывать ошибку чтения байти из сокета. В месте возникновения ты не знаешь является это ошибкой или нет. А знаешь лишь несколькими уровнями выше.


    _>Как это не знаем? На уровне приложения мы всегда знаем должно ли оно завершаться в подобном случае (кстати довольно редкий сценарий по идее).


    На уровне приложения — да. Но это не значит что мы об этом знаем в месте где возникла проблема. Кстати, что там было про уровни и прочее? Что ты будешь делать на уровне, где осуществляется чтение данных из коммуникационного канала, при проблеме с чтением данных из сокета?
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[51]: Вот еще, или я, кажется, читать разучился
    От: ambel-vlad Беларусь  
    Дата: 04.03.13 03:02
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    AV>>Гораздо меньше. Просто не надо каждый вызов функции обрамлять try/catch. Если не знаешь что делать с исключением и ничего полезного не можешь добавить, то не лови его.


    _>Определение классов исключений тоже забывать не надо. )


    Да, я помню это. Но кроме кол-ва строк есть и другие моменты. Например, что ты будешь делать с пропущенным кодом ошибки?

    AV>>try/catch использовать как if/else, то усилий будет больше. Никто не отрицает этого. Если бензопилу использовать как обычную ножовку, то тоже моментально проклянешь ее.


    _>Ну собственно о широте области правильного применения мы тут и спорим.


    в этом топике уже не раз говорили по этому поводу. Например, не знаешь что делать с исключением — не лови его.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[60]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 04.03.13 05:19
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

    E>>Вернёшь ошибку, тот, кто позвал -- разберётся...

    AV>А тот кто позвал тоже не знает что делать с этой ошибкой. Кидаем код ошибки еще выше?
    Что значит "кидаем"?
    Функция "считать байт" может позваться много из откуда. Может из какого-то места, ну там, скажем ждём команды пользователя, а может просто вводим строчку.

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

    AV>Простой пример. Была функция. Не тобой написанная. Но ты ее юзаешь. Написал тесты. Все хорошо. Потом пришла новая версия этой функции. С новым кодом. О котором ты не знал или забыл. Как твои старые тесты это отловят?


    А вдруг она не с новым кодом, а вообще другое делает? Ну там в некоторых случаях не сортирует, а фильтрует жанные, скажем? Откуда ты про это узнаешь?

    С кодом проще, напиши assert, что обработал все варианты...

    AV>Может стоит думать над полезной функциональностью, а не как бы не пропустить какую-либо ошибку. А то если ее забыть, то где и когда она всплывет неизвестно.


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

    AV>Каким образом?

    Должна быть обработка. Формально то, что обработка есть легко проверяется.

    E>>Ну это любой обычный код так выглядит. Скажем никогда не видел std::cout и сервисы из stdio в одной программе?

    AV>Видел. И не такое видел. И что?
    Ну обычное же дело? Ну значит так можно программировать выходит...

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


    Не понятно что конкретно надо написать. Что-то вроде:
    if( !src.read_byte( current_byte ) ) {
        this->peocessErrorInSrc( src );
        return false;
    }
    или что-то ещё?
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[42]: Это-то как раз просто решается...
    От: Erop Россия  
    Дата: 04.03.13 05:25
    Оценка: :)
    Здравствуйте, ambel-vlad, Вы писали:

    AV>То есть в случае ошибки ты будешь либо откатывать проделанное назад либо получить новый инвариант. Так?


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

    AV>Это все отменяется при исключениях? Нет, не отменяется.

    Так я с этого же и начал?
    Как на практике обеспечить тестироване обеспечения базовой гарантии и обеспечить покрытие этими тестами всех сценариев?..
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[43]: Это-то как раз просто решается...
    От: ambel-vlad Беларусь  
    Дата: 04.03.13 05:43
    Оценка:
    Здравствуйте, Erop, Вы писали:

    AV>>То есть в случае ошибки ты будешь либо откатывать проделанное назад либо получить новый инвариант. Так?


    E>Или изменю инвариант...


    А если не изменяешь, то чем тебе исключение в этом вопросе мешают?

    AV>>Это все отменяется при исключениях? Нет, не отменяется.

    E>Так я с этого же и начал?
    E>Как на практике обеспечить тестироване обеспечения базовой гарантии и обеспечить покрытие этими тестами всех сценариев?..

    Так же как и в случае кодов ошибок. Почему в этой части исключения выделяются чем-то особенным?
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[61]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: ambel-vlad Беларусь  
    Дата: 04.03.13 05:51
    Оценка:
    Здравствуйте, Erop, Вы писали:

    E>>>Вернёшь ошибку, тот, кто позвал -- разберётся...

    AV>>А тот кто позвал тоже не знает что делать с этой ошибкой. Кидаем код ошибки еще выше?
    E>Что значит "кидаем"?

    С данном случае означает "возвращаем".

    E>Функция "считать байт" может позваться много из откуда. Может из какого-то места, ну там, скажем ждём команды пользователя, а может просто вводим строчку.


    А может и из места, которое читает очредной кусок данных. И что делаем с ошибкой? Ни в функции чтения байта мы не знаем что с ней делать, в месте вызова этой функции тоже не знаем что с ней делать.

    E>Если второе, то возвращаем, что строчка закончилась аварийно, если первое, что ответа не будет по утере связи и т. д...


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

    AV>>Простой пример. Была функция. Не тобой написанная. Но ты ее юзаешь. Написал тесты. Все хорошо. Потом пришла новая версия этой функции. С новым кодом. О котором ты не знал или забыл. Как твои старые тесты это отловят?


    E>А вдруг она не с новым кодом, а вообще другое делает? Ну там в некоторых случаях не сортирует, а фильтрует жанные, скажем? Откуда ты про это узнаешь?


    E>С кодом проще, напиши assert, что обработал все варианты...


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

    AV>>Может стоит думать над полезной функциональностью, а не как бы не пропустить какую-либо ошибку. А то если ее забыть, то где и когда она всплывет неизвестно.


    E>Почему "ошибку"? Просто предусмотреть все расклады, а не только самый основной...


    Как не забыть эти все? И как потом обнаружить что именно мы забыли?

    AV>>Каким образом?

    E>Должна быть обработка. Формально то, что обработка есть легко проверяется.

    Что обработка есть — да. Что она полная нифига не легко.

    E>>>Ну это любой обычный код так выглядит. Скажем никогда не видел std::cout и сервисы из stdio в одной программе?

    AV>>Видел. И не такое видел. И что?
    E>Ну обычное же дело? Ну значит так можно программировать выходит...

    С этим не спорю. Можно все. Например, в цирке ходят на руках.

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


    E>Не понятно что конкретно надо написать. Что-то вроде:
    if( !src.read_byte( current_byte ) ) {
        this->>peocessErrorInSrc( src );
    E>    return false;
    E>}
    или что-то ещё?


    Чтобы тебе было проще, повторю.

    Покажи не ужас, когда ошибку можно обработать на 4-5 уровней выше нежели ее обнаружение? И чтобы два раза не переписывать, то добавим, что верхняя фунция внутри себя вызывает не одну функцию, а три-пять. И те внутри себя тоже вызывают что-то. И при обработке ошибок на верхнем уровне хотелось бы знать что за ошибка произошла и в какой именно функции. А чтобы еще более весело стало, то функции, в которых возникают ошибки пишутся другими командами. Посему их изменить ты не можешь. А коды ошибок они используют одинаковые.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[44]: Это-то как раз просто решается...
    От: Erop Россия  
    Дата: 04.03.13 07:26
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:


    AV>Так же как и в случае кодов ошибок. Почему в этой части исключения выделяются чем-то особенным?


    Потому, что в типичных программах return'ов раз в 100 меньше, чем мест, откуда может вылететь исключение...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[45]: Это-то как раз просто решается...
    От: ambel-vlad Беларусь  
    Дата: 04.03.13 07:39
    Оценка:
    Здравствуйте, Erop, Вы писали:

    AV>>Так же как и в случае кодов ошибок. Почему в этой части исключения выделяются чем-то особенным?


    E>Потому, что в типичных программах return'ов раз в 100 меньше, чем мест, откуда может вылететь исключение...


    Да? Мест из которых может вылететь исключение столько сколько же и мест откуда возвращается код ошибки. Так что не выходит твои 100.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[62]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 04.03.13 09:09
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

    AV>А может и из места, которое читает очредной кусок данных. И что делаем с ошибкой? Ни в функции чтения байта мы не знаем что с ней делать, в месте вызова этой функции тоже не знаем что с ней делать.


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

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

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

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

    AV>Какие все варианты? Как ты гарантируешь, что не пропустил какой-нибудь вариант?

    Ну, если программа нормально написана, то по уровню понятно что он может вернуть чисто формально даже. Но если таки не понятно, то можно написать assert( false ) в ветке, в которую попадём, если ничего из предусмотренного, например...

    AV>>>Может стоит думать над полезной функциональностью, а не как бы не пропустить какую-либо ошибку. А то если ее забыть, то где и когда она всплывет неизвестно.


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

    AV>Как не забыть эти все? И как потом обнаружить что именно мы забыли?

    Ну так же, как и при остальном программировании не?

    AV>Что обработка есть — да. Что она полная нифига не легко.

    Перднамеренная неполная -- саботаж, за это можно наказать. Непреднамеренная неполная -- редкость.

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


    Тв хочешь, что бы я тебе написал пару тысяч строк кода? Или что такое "уровень", на каждом из которых три-пять функций, а уровней 4-5 штук.
    Это даёт нам примерно 1000 функций, вообще-то.
    И во всём этом коде нельзя как-то интерпретировать отказ в обеспечении основной функциональности?
    Мне трудно понять, что это за код такой. Но есть сильное подозрение, что там чего-то неопроектировали.

    Приведи понятный какой-то стек вызовов и описания окружения, что бы можно было понять что это за 4-5 уровней...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[4]: Tizen 2.0
    От: enji  
    Дата: 04.03.13 11:16
    Оценка:
    Здравствуйте, Erop, Вы писали:

    E>и да, на мой взглаяд симбиан для телефона намногоболее удачная платформа, чем андроид.

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

    Был у меня самсунг на симбиане, недешевый. Сейчас самсунг на андроиде, тоже из верхнего ряда. Андроид как-то поудобнее, программ больше всяких разных. Маркет — кульная штука. Под симбиан оно вроде до РФ не добралось...

    Батарейки хватает дня на три (если в режиме телефона + немного смартфона). Рывков нет, глюков — тоже.

    Проги писать ни под симбиан, ни под андроид не пробовал, так что сравнить не могу.
    Re[5]: Tizen 2.0
    От: Erop Россия  
    Дата: 04.03.13 14:24
    Оценка:
    Здравствуйте, enji, Вы писали:

    E>Был у меня самсунг на симбиане, недешевый. Сейчас самсунг на андроиде, тоже из верхнего ряда. Андроид как-то поудобнее, программ больше всяких разных. Маркет — кульная штука. Под симбиан оно вроде до РФ не добралось...


    Ну так то до РФ...
    Ну и вообще под симиан программ тоже много было.
    Но суть тут вообще не в этом. Телефон в первую очередь должен хорошо основную функциональнсть выполнять, как бы...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[6]: Tizen 2.0
    От: enji  
    Дата: 04.03.13 14:58
    Оценка:
    Здравствуйте, Erop, Вы писали:

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


    ну дык — что симбиановский самсунг жил 2-3 дня, что андроидный... Звонилка в андроиде поудобнее. С другой стороны, между ними 3 года, может и симбиановская бы допилилась
    Re[51]: Вот еще, или я, кажется, читать разучился
    От: maxkar  
    Дата: 04.03.13 15:19
    Оценка: 1 (1) +1
    Здравствуйте, alex_public, Вы писали:

    _>Однако многие программисты расширяют значение термина "ошибка" до чего-то типа "возврат неудачи функции", которое совершенно не обязательно должно прерывать нормальное исполнение программы, а всего лишь направляет по другому сценарию. И в такой ситуации у исключений уже нет никаких особых преимуществ автоматизма, т.к. по нормальному обработка (пускай это и переупаковка исключения всего лишь) такой ошибки происходит на локальном уровне (в отличие от настоящих ошибок, обработчик которых скорее всего один глобальный). Соответственно применяя исключения в такой ситуации мы выполняем лишнюю работу (классы исключений, сам код больше и т.п.) не получая от этого никаких реальных преимуществ.


    Нормально расширяют. Это удобно. Основной критерий — обработка ошибки может быть не в той функции, которая вызвала функцию с ошибкой. Т.е. не в direct caller. А это встречается достаточно часто. А уж для библиотеки так вообще must have — откуда там известно, как программа у пользователя библиотеки устроена и где на самом деле находится обработка "неудачи".

    Более подробно ряд сценариев распишу.

    Первый. Возврат из слоя абстракции, который внутри разделен на несколько процедур. Возврат нелокальный и производится всегда наружу этого слоя (т.е. обрабатываться внутри не будет). Ручками каждый вывод разбирать и оборачивать в коды ошибок — муторно, долго и приводит к ошибкам. Тот же разбор заголовка — неверный формат внутри заголовка обрабатываться не будет, поэтому переход нелокальный (за границу слоя "конфиг файл"). Ошибки более низкого слоя абстракции (IO error) — тоже на этом уровне мы обычно не можем обработать. Это вообще переход ошибки "через слой". Это нормально. Все-таки "нельзя считать профиль потому что там что-то не то" и "нельзя считать файл, потому что диск не читается" — разные ошибки даже с точки зрения пользователя. И решать проблемы нужно по-разному. В первом случае, вероятно, файл не тот. Во втором — либо файл совсем не тот, либо пора обратиться к бэкапу.

    Второй. Управление "уникальностью" кодов ошибок между различными библиотеками. Числовые коды ошибок могут пересекаться. Исключения (при должном именовании) — нет. Поэтому большой зоопарк поддерживать проще. И разбираться в нем проще. Тот же вывод разных кодов ошибок будет разный (см. выше). Вообще, хорошее исключение (не важно, на каком уровне) дает достаточно хорошее описание причины ошибки. Поэтому не нужно спрашивать пользователя "а что там у вас вообще происходит?" а ситуация становится понятна с первого же исключения.

    Третий. Предоставление дополнительной информации об ошибках. Например, при чтении профиля из нескольких файлов один из файлов не найден. Описания "профиль не прочитался" для решения пользователем ну совсем никак не достаточно. Описания "мы не смогли прочитать файл" — тоже. А вот "мы не смогли прочитать файл abc.xml" — вполне нормальное. Вдруг пользователь вспомнит, что только вчера его антивирус нашел что-то подозрительное в файле abc.xml и этот файл теперь живет в карантине? Или пользователь папочку резервно копировал. Но вместо копирования куда-то переместил. Ну и так далее и тому подобное (ссылки на файлы из конфигов, ссылки в интернет, etc, etc...). Сюда же можно отнести и локализацию сообщений об ошибках (а скажите в случае кодов возврата, в какой строке у пользователя конфиг неверен...)

    Четвертый. Грамотно спроектированные исключения образуют отношения master-detail. Я могу обрабатывать (не важно на каком) уровне ошибки "по шаблону". Например, типичная обработка — FileNotFoundException — одна обработка, остальные IOException — другая. Или там станадртный EBADF — это вообще внутренняя ошибка приложения, при которой пора все убивать (потому что у нас инварианты поехали). А вот ECONNRESET можно и пользователю показать, сказав, что у него с сетью проблемы. Ну или там в зависимости от ошибки будем пытаться запрос к базе через некоторое время повторить (ошибка связи/транзакция накрылась) или не будем (синтаксис запроса неверен, какой смысл еще раз получать ту же ошибку?).

    Пятый. Проброс ошибки "насквозь" слоя абстракции. При грамотном дизайне это, как ни странно, достаточно частая ситуация. У нас выделен какой-то алгоритм/класс и т.п. Этот класс имеет зависимости, получаемые в конструкторах (аргументах метода и т.п.). Возможность ошибок там мы предусматриваем (соответствующие типы исключений). Но вот с самими ошибками мы ничего сделать не можем — интерфейс слишком общий. Т.е. мы можем обнаружить ошибку, вернуть инварианты, затем передать ошибку выше. А вот "внешний" слой с этой ошибкой может что-то разумное и сделать. Он ведь знает, что конкретно передавал в зависимости, знает ошибки этого слоя и т.п. Что характерно, "на уровне ниже" (в той самой переданной зависимости) мы не можем обработать ошибку. Ну как мы там можем ошибку сети обработать, например? При повторной закачке все может быть уже по-другому. Поэтому нужно возвращаться через несколько слоев абстракции. Пример — банальные read/write, которые с любым файловым дескриптором работают (и возвращать нужно через несколько слоев, на тот уровень, где дескрипторы были созданы). Но read/write исключения не кидают по историческим причинам, так что у меня к ним претензий нет. Можно еще вспомнить про п. 2 и то, что зависимостей может быть несколько и в них могут использоваться различные библиотеки.

    Вот все это на "кодах возврата" делается не очень хорошо...
    ку
    Re[59]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: maxkar  
    Дата: 04.03.13 16:15
    Оценка:
    Здравствуйте, Erop, Вы писали:

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


    M>>А что мешает то? В catch мы попадаем, если есть ошибка. Задача catch — восстановить все варианты блока try{}catch{}. Если мы имеем некий формализм по описанию исключений, мы знаем, в какой строке выше какие исключения могут происходить. В чем проблема то? Если ошибки нет, мы в catch не попадем. Если ошибку не обработали, то мы вообще в весь остаток функции не попадем.


    E>Проблема в структуре получающихся предикатов.

    E>Их либо вообще не получается написать, либо получается, что всё зависит от всего.
    E>Ну то есть в НОРМАЛЬНОЙ программе кроме того, что у нас будет функция, read_profile, которая спрячем внутри себя подробноти как там и откуда итается профиль, за одно и предусловие этой функции свернётся в "профиль доступен", А в программе которая написана, так что у нас стек вызовов глубиной а пять функций. шириной в 10 и наружу торчат 100500 исключений, то там получится предусловие вида " на таком-то смещее в таком-то файле стоиит цифра, а не буква" и так 100500 раз...
    E>Собственно полезная логика в этом шуме просто утонет бесследно и всё. А так пролем никаких нет

    В случае с исключениями все так же прекрасно свернется в то же предусловие "профиль доступен" для той же функции read_profile. В качестве бонуса, я получаю постусловие "а если вдруг предусловие не выполнено, после выполнения функции мы имеем какое-то исключение". При более формальном подходе мы будем даже знать, что у нас есть IOException в случае нарушения предусловия. А вот как вы будете гарантировать ваше предусловие я плохо представляю. Там же на нижнем уровне read может с EIO завершиться, например. Если везде коды ошибок проверять, то вы получите if'ы через строчку. Т.е. треть программы у вас будут if'ы, треть — return'ы от этих if'ов и треть — логика программы. Можно все это в одну функцию заинлайнить, сильно легче от этого не станет. А количество функций здесь определяется не столько подходом к архитектуре, сколько самой задачей. Какая есть структура данных в задаче, такую и придется читать. Где-то в теме про сложность подобное называли "essential complexity". Так что ваш предикат "профиль доступен" точно так же собирается по остальным функциям (из их предусловий) и имеет настолько же ужасный вид. Ну и постусловие "если профиль не доступен, мы получаем в результатет вызова функции ошибку доказывается одинаково в процедурном стиле и на исключениях.

    В общем, с неидеальным внешним миром программа на кодах ошибок примерно такая же будет. И предикаты такие же . Точнее, на исключениях предусловие будет "профиль доступен или профиль не доступен". А постусловие "профиль таки доступен и у нас есть результат или профиль не доступен и у нас есть исключение". У вас после разборки с неидеальным миром (от которого далеко не всегда можно уйте) — то же самое. Если же вы вздумаете делать прогон по файлу с целью гарантии предусловия, то на ровном месте получите уязвимость, когда файл изменяется между проверкой и чтением. В общем, после поправки на неидеальность мира — для доказательства не будет разницы, исключения там или куча return в теле функций.

    Если что, я не предлагаю какую-то "гарантированную" логику делать на исключениях. Там как раз все в процедурный или даже функциональный стиль переписывается (в функциональном предикаты еще проще ведь, там только применения функций и есть). Только вот в 95% случаев мы в конце концов упираемся во взаимодействие со внешним миром (файлы/сеть/пользователь), оттуда и растет большинство исключений. Нарушение внутренних инвариантов и прочее — как раз особые ситуации, которые нужно рассматривать в каждом отдельном случае, там не будет общих решений.
    Re[61]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: maxkar  
    Дата: 04.03.13 16:53
    Оценка:
    Здравствуйте, Erop, Вы писали:

    E>Ну мы же обсуждаем РЕАЛЬНЫЕ практики, а не гипотетические?..

    E>И с самого начала эта тема была в С++/С, так что плюсовые к тому же.
    E>В той же Яве всё-таки есть GC, что очень упрощает жизнь программам с исключениями.
    E>Гарантии безопасности проще намного выглядят и обеспечить их тоже проще...

    Вот с этим согласен. С памятью руками неудобно работать. Но те же c++ как раз исключениями дают какую-никакую, а доказуемость тех же освобождений памяти.
    X *x = new X();
    try {
    //...
    } catch {
      delete x;
      throw;
    }

    Аналогично с дескрипторами файлов и т.п. Я предлагаю только такую форму анализировать как try-finally (обработку исключений завернуть внутри в другой блок). Вот по этому коду можно доказать, что delete x будет вызвано всегда, когда X успешно создался (в силу семантики try/catch). На кодах возврата такое не очень хорошо записывается и доказывается. Там или выходы сразу отсюда (и копипаста деинициализации), или куча if'ов в конце, чтобы проверить, на каком этапе что сломалось. Я помню, как оно на C выглядит. GC, естественно, помогает, так как 90% ресурсов — память, поэтому в этих случаях можно try/finally или обертки с деструкторами не писать.

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


    Если говорить про внешний мир, то разницы с обработкой кодов ошибок нет. А это 95% случаев использования исключений (в нормальной программе, конечно). Ну не покроете вы внешний мир предикатами. Так что в процедурном стиле будет аналогия исключений, либо гораздо больше UB, чем в программе на исключениях. Естественно, я говорю только про программы с наличием архитектуры и некоторых соглашений по исключениям (навроде упомянутого — "источник — внешний мир").

    E>Не очень понятно, что такое "какая-нибудь ошибка"?..

    Меня как раз стэк интересовал, из следующего вопроса. Могу еще, конечно, подкинуть вопрос. На вызов close(fd) вернул -1, errno == EIO. Вопрос — в каком же теперь состоянии находится файл? Нужно ли делать еще раз close (и если да, то сколько) или файловый дескриптор уже помечен как доступный и у меня в дальнейшем не исчерпаются эти дескрипторы? Мой man на этот вопрос ответа не дает.

    M>>Вопрос: как доказать, что мы не поймаем переполнение стека в процессе очистки уже выделенных ресурсов?


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


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

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

    E>Я бы на С++ намеренно переполнять стек не стал бы.

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

    E>Можно пример алгоритма, о котором речь, кстати?

    Когда вопрос задавал, что-то вроде XML DOM, описанного выше, имел в виду. Ну и любая древовидная структура из внешнего источника (задаваемого пользователем). А вот теперь вспомнил, что совсем недавно писал библиотечку топологической сортировки. Не нашел нигде неинтрузивной топосортировки с описанием циклов в случае ошибок. Все кидают неинформативное "у нас есть цикл", а я хочу пользователю написать, где же у него цикл. Вот там используется рекурсия, на ней все коротко и просто. После вашего вопроса понял, что туда стоит поставить fallback и сделать нерекурсивный алгоритм (не хочу по-умолчанию сильно мучать heap). Нужно теперь найти время и все закодить .
    Re[57]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: maxkar  
    Дата: 04.03.13 17:18
    Оценка: +1
    Здравствуйте, Erop, Вы писали:

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


    E>Ну, как бы, в нормальных программах принято скрывать подробности реализации от клиентского кода.

    E>То есть если тебе функция fopen вернёт что-то вроде ("список в таком-то блоке исчерпан") вместо "нет файла" или там "нет доступа"...

    В принципе — нормальная ошибка. Я не знаю, правда, как там в C++ с отловом наследников но в иерархии ESomeFSListExhausted extends ENoSpaceLeftOnDevice extends IOException смотрелось бы нормально. Как минимум пользователю выводить стоит разные ошибки. Я бы, например, увидев ESomeFSListExhausted, мог бы подумать, сделать backup и пересоздать новую файловую систему с увеличенным размером какого-то блока. Ситуация реальная, я tmpfs подстраивал, на которой в какой-то момент inodes закончились.

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

    В контексте error prone как раз на код ошибки гораздо проще забить (не проверять возвращаемое значение), чем в случае с исключениями (которое полетит мимо и дальше). Даже в man'е по close написано . Код с исключениями, конечно, тоже требует правильного использования управляемых оберток или try/finally (try/catch{...;throw;} для C++). Но для однотипных блоков на исключениях получается меньше писанины (одна обретка вместо if (error) через строку).
    Re[7]: Tizen 2.0
    От: Erop Россия  
    Дата: 04.03.13 18:22
    Оценка:
    Здравствуйте, enji, Вы писали:

    E>ну дык — что симбиановский самсунг жил 2-3 дня, что андроидный...


    Про самсунг ничего не знаю. Оригинальные телефоны с симбиан бывало и подольше жили...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[60]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 04.03.13 18:36
    Оценка:
    Здравствуйте, maxkar, Вы писали:

    M>В случае с исключениями все так же прекрасно свернется в то же предусловие "профиль доступен" для той же функции read_profile.

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

    Я согласен, что если ты все исключения с нижнего уровня отловиш и оттранслируешь в какие-то исключения внешнего уровня, то всё свернётся, только это проще эффективнее и безопаснее сделать на том, что ты называешь "коды возврата", но можно и на исключениях, конечно, только не понтно в чём профит

    А если речь идёт таки о том, что со всей иерархиии стека вызовов все абы что кидают, и снаружи это всё вылетает, то что-то как-то не верится, что "само свернётся", таки

    M>А вот как вы будете гарантировать ваше предусловие я плохо представляю.

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


    M>Только вот в 95% случаев мы в конце концов упираемся во взаимодействие со внешним миром (файлы/сеть/пользователь), оттуда и растет большинство исключений.

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


    M>Нарушение внутренних инвариантов и прочее — как раз особые ситуации, которые нужно рассматривать в каждом отдельном случае, там не будет общих решений.


    Не, нарушение внутренних инвариантов -- это assert, их не рассматривать в каждом случае надо и не обрабатывать, а исправлять код. В тмо я абсолютно согласен с Дворкиным...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[62]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 04.03.13 18:51
    Оценка:
    Здравствуйте, maxkar, Вы писали:

    M>Аналогично с дескрипторами файлов и т.п. Я предлагаю только такую форму анализировать как try-finally (обработку исключений завернуть внутри в другой блок). Вот по этому коду можно доказать, что delete x будет вызвано всегда, когда X успешно создался (в силу семантики try/catch). На кодах возврата такое не очень хорошо записывается и доказывается.

    Ну в С++ на эту тему есть аки RAII там всякие... Но, в целом и finlly и деструкторы автоматических объектов -- это всё про одно и то же. И к обработке ошибок это всё непосредственного отношения не имеет.
    Скажем мы насоздавали каких-то структур и что-то с их помощью ищем. Как нашли -- прямо из недр цикла выходим. Как бы никаких ошибок и исключений тут и близк нет. а возврат из середины функции есть...

    M>Если говорить про внешний мир, то разницы с обработкой кодов ошибок нет. А это 95% случаев использования исключений (в нормальной программе, конечно). Ну не покроете вы внешний мир предикатами. Так что в процедурном стиле будет аналогия исключений, либо гораздо больше UB, чем в программе на исключениях. Естественно, я говорю только про программы с наличием архитектуры и некоторых соглашений по исключениям (навроде упомянутого — "источник — внешний мир").


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

    M>Меня как раз стэк интересовал, из следующего вопроса. Могу еще, конечно, подкинуть вопрос. На вызов close(fd) вернул -1, errno == EIO. Вопрос — в каком же теперь состоянии находится файл?

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

    M>Так не всегда же получается. Вот я XML в виде DOM из файла считал. Дом оказался большой, но считался. Кто-нибудь мне гарантирует, что у него потом деструктор нормально отработает, а не исчерпает стек в самый неподходящий момент в результате обхода дочерних узлов? Ну и еще можно чего-нибудь именно со внешним миром придумать (и древовидной структурой, чтобы не линеаризовалось).


    Ну в целом это не единственный, но один из понятных аргуентов за то, что вещи вроде DOM надо грузить, создавая ноды и все их данные на отдельном аллокаторе, а потом грохать аллокатор, а не модель поэлементно...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[58]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 04.03.13 18:54
    Оценка:
    Здравствуйте, maxkar, Вы писали:

    M>В контексте error prone как раз на код ошибки гораздо проще забить (не проверять возвращаемое значение), чем в случае с исключениями (которое полетит мимо и дальше).


    Ну просто на коммит вешаешь статиеский анализатор с проверкой того, что коды ошибок обрабатываются и всё...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[60]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: Erop Россия  
    Дата: 04.03.13 21:43
    Оценка:
    Здравствуйте, maxkar, Вы писали:

    M>В случае с исключениями все так же прекрасно свернется в то же предусловие "профиль доступен" для той же функции read_profile.

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

    Я согласен, что если ты все исключения с нижнего уровня отловиш и оттранслируешь в какие-то исключения внешнего уровня, то всё свернётся, только это проще эффективнее и безопаснее сделать на том, что ты называешь "коды возврата", но можно и на исключениях, конечно, только не понтно в чём профит

    А если речь идёт таки о том, что со всей иерархиии стека вызовов все абы что кидают, и снаружи это всё вылетает, то что-то как-то не верится, что "само свернётся", таки

    M>А вот как вы будете гарантировать ваше предусловие я плохо представляю.

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


    M>Только вот в 95% случаев мы в конце концов упираемся во взаимодействие со внешним миром (файлы/сеть/пользователь), оттуда и растет большинство исключений.

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


    M>Нарушение внутренних инвариантов и прочее — как раз особые ситуации, которые нужно рассматривать в каждом отдельном случае, там не будет общих решений.


    Не, нарушение внутренних инвариантов -- это assert, их не рассматривать в каждом случае надо и не обрабатывать, а исправлять код. В этом я абсолютно согласен с Дворкиным...
    Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
    Re[63]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: ambel-vlad Беларусь  
    Дата: 04.03.13 22:39
    Оценка: +1
    Здравствуйте, Erop, Вы писали:

    AV>>А может и из места, которое читает очредной кусок данных. И что делаем с ошибкой? Ни в функции чтения байта мы не знаем что с ней делать, в месте вызова этой функции тоже не знаем что с ней делать.


    E>Обычно бывает низкоуровневая функция типа "считать блок" через которую реализована более высокоуровневая "считать буфер"...

    E>"Считать блок" обычно имеет кучу раскладов, тое низкоуровневых.
    E>"считать буфер" уже имеет более высокоуровневые причины отказов.

    То есть заменяем одни коды ошибок другими кодами.

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


    Переписать код ошибки на другой — это называется знаем что с чем делать?

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

    E>В смысле "спрятать"?

    На более высоком уровне я буду знать только что строчка завалилась аварийно. Какова причина аварии? А фиг его знает. Как будем исправлять проблему? А собственно какую именно проблему? Мы же не знаем что именно произошло.

    AV>>Какие все варианты? Как ты гарантируешь, что не пропустил какой-нибудь вариант?

    E>Ну, если программа нормально написана, то по уровню понятно что он может вернуть чисто формально даже.

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

    AV>>>>Может стоит думать над полезной функциональностью, а не как бы не пропустить какую-либо ошибку. А то если ее забыть, то где и когда она всплывет неизвестно.


    E>Ну это же уже тоже обсуждалось. Если надёжность и вообще поддержка пользователей нас мало парят, то та и нада. Только тогда не понятно зачем вообще на какие-то базовые гарантии тратиться, и вообще зачем на плюсах это делать...


    При использовании кодов ошибок эти гарантии остаются. Только не в профиль, а в фас.

    AV>>Как не забыть эти все? И как потом обнаружить что именно мы забыли?

    E>Ну так же, как и при остальном программировании не?

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

    AV>>Что обработка есть — да. Что она полная нифига не легко.

    E>Перднамеренная неполная -- саботаж, за это можно наказать. Непреднамеренная неполная -- редкость.

    Как ты собираешься проверять, что обработка полная?

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


    E>Тв хочешь, что бы я тебе написал пару тысяч строк кода? Или что такое "уровень", на каждом из которых три-пять функций, а уровней 4-5 штук.

    E>Это даёт нам примерно 1000 функций, вообще-то.

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

    E>И во всём этом коде нельзя как-то интерпретировать отказ в обеспечении основной функциональности?


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

    E>Приведи понятный какой-то стек вызовов и описания окружения, что бы можно было понять что это за 4-5 уровней...


    Упрощенно:
    [ccode]

    void F(void) {
    F1_1();
    F1_2();
    F1_3();
    F1_4();
    F1_5()
    }

    void F1_1() {
    F2_1();
    ...
    }

    void F2_1() {
    F3_1();
    ...
    }

    void F3_1() {
    F4_1();
    ...
    }

    int F4_1() {
    ...
    return 1; //return error code
    ...
    }

    [/ccode]]

    В функции F4_1 возникла проблема. Как ее обработать ты знаешь только в функции F. Измени код чтобы было видно как ты будешь это обрабатывать.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[60]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: alex_public  
    Дата: 05.03.13 04:02
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

    AV>На уровне приложения — да. Но это не значит что мы об этом знаем в месте где возникла проблема. Кстати, что там было про уровни и прочее? Что ты будешь делать на уровне, где осуществляется чтение данных из коммуникационного канала, при проблеме с чтением данных из сокета?


    Да не важно на каком уровне код принимает решение о том ошибка это или нет. Мы то (программисты) всё равно знаем это решение, кодируя нижний уровень. У нас же не библиотека, а приложение... Ну а если на этом самом высоком уровне возможны оба варианта решения, то тогда просто использовать какой удобнее в конкретном случае.
    Re[52]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 05.03.13 04:13
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

    AV>Да, я помню это. Но кроме кол-ва строк есть и другие моменты. Например, что ты будешь делать с пропущенным кодом ошибки?


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

    AV>в этом топике уже не раз говорили по этому поводу. Например, не знаешь что делать с исключением — не лови его.


    Вопрос скорее в том надо ли кидать. )))
    Re[52]: Вот еще, или я, кажется, читать разучился
    От: alex_public  
    Дата: 05.03.13 04:43
    Оценка:
    Здравствуйте, maxkar, Вы писали:

    M>Нормально расширяют. Это удобно. Основной критерий — обработка ошибки может быть не в той функции, которая вызвала функцию с ошибкой. Т.е. не в direct caller. А это встречается достаточно часто. А уж для библиотеки так вообще must have — откуда там известно, как программа у пользователя библиотеки устроена и где на самом деле находится обработка "неудачи".


    Что касается библиотек, то на мой взгляд правильные C++ библиотеки должны реализовывать обе возможности. Что мы и видим например в Boost'е. Хотя бывают и такие ошибки (опять же выделение памяти и т.п.), которые гарантированно лучше исключениями. )))

    M>Первый. Возврат из слоя абстракции, который внутри разделен на несколько процедур. Возврат нелокальный и производится всегда наружу этого слоя (т.е. обрабатываться внутри не будет). Ручками каждый вывод разбирать и оборачивать в коды ошибок — муторно, долго и приводит к ошибкам. Тот же разбор заголовка — неверный формат внутри заголовка обрабатываться не будет, поэтому переход нелокальный (за границу слоя "конфиг файл"). Ошибки более низкого слоя абстракции (IO error) — тоже на этом уровне мы обычно не можем обработать. Это вообще переход ошибки "через слой". Это нормально. Все-таки "нельзя считать профиль потому что там что-то не то" и "нельзя считать файл, потому что диск не читается" — разные ошибки даже с точки зрения пользователя. И решать проблемы нужно по-разному. В первом случае, вероятно, файл не тот. Во втором — либо файл совсем не тот, либо пора обратиться к бэкапу.


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

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

    M>Второй. Управление "уникальностью" кодов ошибок между различными библиотеками. Числовые коды ошибок могут пересекаться. Исключения (при должном именовании) — нет. Поэтому большой зоопарк поддерживать проще. И разбираться в нем проще. Тот же вывод разных кодов ошибок будет разный (см. выше). Вообще, хорошее исключение (не важно, на каком уровне) дает достаточно хорошее описание причины ошибки. Поэтому не нужно спрашивать пользователя "а что там у вас вообще происходит?" а ситуация становится понятна с первого же исключения.


    Нууу тут можно согласиться, если говорим о Java. В C++ я не видел общепринятой стратегии именования. Там даже потомка общего по сути нет — в каждом приложение/библиотеке может быть свой прародитель. Хотя в последнее время многие стали использовать для этого boost::exception, т.к. это позволяет автоматически делать такие http://www.boost.org/doc/libs/1_53_0/libs/exception/doc/motivation.html вещи. Но это далеко не правило, а только тенденция...

    M>Третий. Предоставление дополнительной информации об ошибках. Например, при чтении профиля из нескольких файлов один из файлов не найден. Описания "профиль не прочитался" для решения пользователем ну совсем никак не достаточно. Описания "мы не смогли прочитать файл" — тоже. А вот "мы не смогли прочитать файл abc.xml" — вполне нормальное. Вдруг пользователь вспомнит, что только вчера его антивирус нашел что-то подозрительное в файле abc.xml и этот файл теперь живет в карантине? Или пользователь папочку резервно копировал. Но вместо копирования куда-то переместил. Ну и так далее и тому подобное (ссылки на файлы из конфигов, ссылки в интернет, etc, etc...). Сюда же можно отнести и локализацию сообщений об ошибках (а скажите в случае кодов возврата, в какой строке у пользователя конфиг неверен...)


    Вообще то для таких вещей есть классические решения. Типа функций GetLastError/SetLastError с буфером где-нибудь в tls.

    M>Четвертый. Грамотно спроектированные исключения образуют отношения master-detail. Я могу обрабатывать (не важно на каком) уровне ошибки "по шаблону". Например, типичная обработка — FileNotFoundException — одна обработка, остальные IOException — другая. Или там станадртный EBADF — это вообще внутренняя ошибка приложения, при которой пора все убивать (потому что у нас инварианты поехали). А вот ECONNRESET можно и пользователю показать, сказав, что у него с сетью проблемы. Ну или там в зависимости от ошибки будем пытаться запрос к базе через некоторое время повторить (ошибка связи/транзакция накрылась) или не будем (синтаксис запроса неверен, какой смысл еще раз получать ту же ошибку?).


    Не очень понятно чем в этом исключения лучше. Разве что тем, что catch автоматом это отлавливает и не надо писать лишний if. Ну так и классы исключений тоже писать тогда не надо.

    M>Пятый. Проброс ошибки "насквозь" слоя абстракции. При грамотном дизайне это, как ни странно, достаточно частая ситуация. У нас выделен какой-то алгоритм/класс и т.п. Этот класс имеет зависимости, получаемые в конструкторах (аргументах метода и т.п.). Возможность ошибок там мы предусматриваем (соответствующие типы исключений). Но вот с самими ошибками мы ничего сделать не можем — интерфейс слишком общий. Т.е. мы можем обнаружить ошибку, вернуть инварианты, затем передать ошибку выше. А вот "внешний" слой с этой ошибкой может что-то разумное и сделать. Он ведь знает, что конкретно передавал в зависимости, знает ошибки этого слоя и т.п. Что характерно, "на уровне ниже" (в той самой переданной зависимости) мы не можем обработать ошибку. Ну как мы там можем ошибку сети обработать, например? При повторной закачке все может быть уже по-другому. Поэтому нужно возвращаться через несколько слоев абстракции. Пример — банальные read/write, которые с любым файловым дескриптором работают (и возвращать нужно через несколько слоев, на тот уровень, где дескрипторы были созданы). Но read/write исключения не кидают по историческим причинам, так что у меня к ним претензий нет. Можно еще вспомнить про п. 2 и то, что зависимостей может быть несколько и в них могут использоваться различные библиотеки.


    Да, я согласен что в случае прямого проброса ошибки на один или несколько уровней выше, исключения становятся удобнее кодов возврата. Но на мой взгляд при правильном проектирование потребность в такой схеме возникает всё же довольно редко.
    Re[62]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: alex_public  
    Дата: 05.03.13 04:58
    Оценка:
    Здравствуйте, maxkar, Вы писали:

    M>Вот с этим согласен. С памятью руками неудобно работать. Но те же c++ как раз исключениями дают какую-никакую, а доказуемость тех же освобождений памяти.

    M>
    M>X *x = new X();
    M>try {
    M>//...
    M>} catch {
    M>  delete x;
    M>  throw;
    M>}
    M>

    M>Аналогично с дескрипторами файлов и т.п. Я предлагаю только такую форму анализировать как try-finally (обработку исключений завернуть внутри в другой блок). Вот по этому коду можно доказать, что delete x будет вызвано всегда, когда X успешно создался (в силу семантики try/catch). На кодах возврата такое не очень хорошо записывается и доказывается. Там или выходы сразу отсюда (и копипаста деинициализации), или куча if'ов в конце, чтобы проверить, на каком этапе что сломалось. Я помню, как оно на C выглядит. GC, естественно, помогает, так как 90% ресурсов — память, поэтому в этих случаях можно try/finally или обертки с деструкторами не писать.

    Ээээ, это немного не по теме, но не могу не заметить что ТАК с указателями в C++ не работают. Это какой-то мутантный вариант между чистым C и C++. По нормальному должно быть unique_ptr<X> x(new X()); и никаких delete далее вообще. Ну и соответственно память будет автоматически гарантировано освобождена и при любых исключениях далее и при просто return из любой точки.

    M>Если говорить про внешний мир, то разницы с обработкой кодов ошибок нет. А это 95% случаев использования исключений (в нормальной программе, конечно).


    Кстати, а вот лично я (Егор может по другому думает, с точки зрения подхода Дейкстры) никогда и не утверждал что у обработки с кодами ошибок есть какие-то преимущества. Я тоже считаю что разницы с исключениями нет. И вот как раз по этому их и не надо (в большинстве случаев, кроме специально оговоренных) использовать! Т.к. разницы в результате нет, а усилий на реализацию исключения требуют всё же чуть больших.
    Re[61]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: ambel-vlad Беларусь  
    Дата: 05.03.13 06:20
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    AV>>На уровне приложения — да. Но это не значит что мы об этом знаем в месте где возникла проблема. Кстати, что там было про уровни и прочее? Что ты будешь делать на уровне, где осуществляется чтение данных из коммуникационного канала, при проблеме с чтением данных из сокета?


    _>Да не важно на каком уровне код принимает решение о том ошибка это или нет. Мы то (программисты) всё равно знаем это решение, кодируя нижний уровень. У нас же не библиотека, а приложение...


    И что мы знаем в функции чтения байта из коммуникационного канала?

    _>Ну а если на этом самом высоком уровне возможны оба варианта решения, то тогда просто использовать какой удобнее в конкретном случае.


    В смылсе "оба варианта"? Что такое в данном случае вариант?
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[53]: Вот еще, или я, кажется, читать разучился
    От: ambel-vlad Беларусь  
    Дата: 05.03.13 06:20
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    AV>>Да, я помню это. Но кроме кол-ва строк есть и другие моменты. Например, что ты будешь делать с пропущенным кодом ошибки?


    _>А в чём отличие от пропущенного исключения?


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

    _>Как и в коде с кодами возврата.


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

    AV>>в этом топике уже не раз говорили по этому поводу. Например, не знаешь что делать с исключением — не лови его.


    _>Вопрос скорее в том надо ли кидать. )))


    А что делать? Возвращать код ошибки?
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[62]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: alex_public  
    Дата: 05.03.13 06:43
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

    AV>И что мы знаем в функции чтения байта из коммуникационного канала?


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

    AV>В смылсе "оба варианта"? Что такое в данном случае вариант?


    В смысле что данная ситуация может интерпретироваться и как ошибка и как нормальное поведение, в зависимости от каких-то сторонних факторов. Но это не так что бы особо часто бывает.
    Re[63]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: ambel-vlad Беларусь  
    Дата: 05.03.13 07:01
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    AV>>И что мы знаем в функции чтения байта из коммуникационного канала?


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


    Функция читает байт. И обламывается. Что будем делать?

    AV>>В смылсе "оба варианта"? Что такое в данном случае вариант?


    _>В смысле что данная ситуация может интерпретироваться и как ошибка и как нормальное поведение, в зависимости от каких-то сторонних факторов.


    ОК. Здесь у нас нет разночтения. Это хорошо. Так что будет делать в точке возникновения проблемы, не зная ошибка это или нет?

    _>Но это не так что бы особо часто бывает.


    В твоих приложения? Верю.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[64]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: alex_public  
    Дата: 05.03.13 15:56
    Оценка:
    Здравствуйте, ambel-vlad, Вы писали:

    AV>Функция читает байт. И обламывается. Что будем делать?


    Ну я же уже говорил что это странно иметь такую абстрактную функцию в приложение. Это скорее на библиотеку похоже. А в приложение у нас функции имеют какой-то конкретный смысл. Вот мы обсуждали пример с профилем и там на самом низком уровне была функция чтения одного int'a. По сути это же тоже функция чтения байта (ну или 4-ёх), однако в приложение это именно функция чтения поля конфига, а не чтения байта. Соответственно зная глобальную стратегию приложения на этот счёт (умираем при кривом конфиге или же работает на дефолтных настройках) мы легко можем определить и оптимальное поведение той самой низкоуровневой функции в случае ошибки.

    А вообще такие функции действительно чаще всего берут из каких-то библиотек. И если библиотека качественная, то там будет оба варианта реализации. А мы уже выбираем нужный как раз в зависимости от того, какую роль эта функция будет иметь в контексте данного приложения.
    Re[65]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: ambel-vlad Беларусь  
    Дата: 05.03.13 23:38
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    AV>>Функция читает байт. И обламывается. Что будем делать?


    _>Ну я же уже говорил что это странно иметь такую абстрактную функцию в приложение. Это скорее на библиотеку похоже.


    библиотека — это что? Отдельная dll?

    _>А в приложение у нас функции имеют какой-то конкретный смысл. Вот мы обсуждали пример с профилем и там на самом низком уровне была функция чтения одного int'a. По сути это же тоже функция чтения байта (ну или 4-ёх), однако в приложение это именно функция чтения поля конфига, а не чтения байта. Соответственно зная глобальную стратегию приложения на этот счёт (умираем при кривом конфиге или же работает на дефолтных настройках) мы легко можем определить


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

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


    Из каких вариантов мы выбираем?
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
    Re[59]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: maxkar  
    Дата: 06.03.13 14:55
    Оценка: 4 (1)
    Здравствуйте, Erop, Вы писали:

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


    Вы это серьезно? Это же застрелиться можно будет. Для начала нужно будет для каждой функции сказать, возвращает она код ошибки или нет (и что это за код). В том числе и на безобидные тотальные функции вроде всей математики. Далее, нужно будет долго учить анализатор тому, что значит "обработка кодов ошибок". Ошибка "не удалился файл" вполне может игнорироваться для определенных файлов. Или, в зависимости от кода и типа, выдаваться пользователю, например (а вот file not exists выдавать не нужно). Потом у вас встанет еще вопрос о "тотальности" обработки ошибок — нужно ведь убедиться не в том, что "какие-то" ошибки обработаны, а в том, что "обработаны все ошибки, которые нужно было обработать". И ладно, если вы используете числовые коды, а что делать в условиях необходимости предоставить более подробную информацию об ошибке? В случае, если у нас поведение параметризуется внешне? В качестве примера последнего — я делаю парсер языка программирования и очень хочу сделать его "полиморфным" по типу. Т.е. Парсер самого языка получает в качестве параметра "TypeParser". Он достаточно абстрактный и возвращает что-то вроде void *. Там в идеале type parameter (generic и т.п.), но только не времени компиляции, а времени выполнения... Т.е. правильная сигнатура Program<T> readProgram(InputStream, TypeParser<T>), конкретный TypeParser будет передан во время выполнения. Очевидно, ошибки парсера нужно корректно передавать наверх (чтобы пользователю вывести, например). Как вы будете все это на кодах ошибок делать? С глобальной переменной для протаскивания информации об ошибке? Или через "полиморфные" коды ошибок?

    Но все, что выше, не является причиной стреляться. Причиной стреляться является печалька в "аппликативном" контексте. Примером объяснить проще всего:
    static SomeThing parseSomeThing(JSONObject jsonObject) {
      return new SomeThing(getLong(jsonObject, "id"), getString(jsonObject, "name"), getString(jsonObject, "description"));
    }

    json в данном случае пришел извне (веб-приложение). Очевидно, что в процессе выполнения метода могут возникнуть ошибки в трех местах. Которые в параметрах передаются. Поэтому для проверки кодов ошибок нужно все это развернуть в переменные и написать еще по несколько if'ов. Как-то многословно получается. На исключениях — запросто. Причем исключения — не завершение приложения. Всего-лишь отправка ответа "что-то у вас не так с форматом" (можно и поле указать). В другом контексте подобное могло быть на pull данных из удаленной системы, в этом случае один из вариантов поведения — подождать и повторить запрос. Пример почти реальный — подобный парсинг у меня на scala и одной inlnie-строкой в разборе запроса. На кодах ошибок (все с внешним миром) все было бы очень и очень длинно.
    Re[61]: Слушайте, люди добрые, а правда, есть мат аппарат анализа кода с иключен
    От: maxkar  
    Дата: 06.03.13 15:24
    Оценка: 1 (1)
    Здравствуйте, Erop, Вы писали:

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


    M>>В случае с исключениями все так же прекрасно свернется в то же предусловие "профиль доступен" для той же функции read_profile.

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

    Это еще почему? Да пусть на том же парсере конфигов многострадальном.
    //* Предусловие: istream not null, istream.read() не бросает BadConfigException, 
      * может бросать любое другое исключение
    //* Постусловие: Либо
      *   1) В потоке удалось прочитать последовательность байт, которая не является
      *      началом ни одного валидного конфига => На выходе искюлчение И istream не закрыт
      *   2) Произошла ошибка чтения потока (istream.read выбросил исключение) => 
      *      на выходе то же исключеие И istream не закрыт
      *   3) В потоке удалось прочитать валидный конфиг, но за ним следуют еще данные =>
      *      Ошибка BadConfigException И istream не закрыт
      *   4) Последовательность байт соответствует валидному конфигу И за ними нет
      *      лишних данных => Функция завершилась успешно, вернула Config 
      *      соответствующий байтам И istream не закрыт И istream находится в конце потока
      *//
    def parseConfig(istream : Inputtable) : Config {
      val header = readConfigHeader(istream);
      val body = readConfigBody(istream);
      val footer = readConfigFooter(istream);
      if (!istream.atEof())
        throw new BadConfigException("Trailing data");
      return new Config(header, body, footer).
    }

    Надеюсь, не проблема, что на scala? . Предикаты на read* подобны исходному (без п. 3). Семантика операционная, а не декларативная, так как мы работаем с реальным миром и ограничить его предикатами нельзя. Доказываем:
    1. Первая строчка. Либо поток начинается тем, что не является началом заголовка конфига (тогда выход по условию 1). Либо мы не дочитали достаточно данных, чтобы сказать что-то определенное (и тогда у нас летит исключение по п. 2). Либо у нас успешный заголовок конфига в переменной header (и какие-то байты из потока прочитаны).
    2. Вторая строчка. К этому моменту прочитан "успешный заголовок". Т.е. пока "прочитанная часть" может быть началом валидного конфига (так как она является заголовком какого-то конфига). Далее по пунктам аналогично. Либо некооректное body и мы обнаружили некорректный префикс, либо ошибка потока (и префикс к тому моменту корректен), либо есть результат body.
    3. Третья строчка. Аналогично.
    4. Проверка конца файла — это проверка п. 3 из предиката.

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

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


    Кода писать меньше. Выгодно если у нас много операций в "небезопасной" среде идет рядом друг с другом. Ну и "аппликативный контекст" в параллельной ветке (new SOmeObject(json.getLong(...), json.getString(...), json.getString(...));

    E>А если речь идёт таки о том, что со всей иерархиии стека вызовов все абы что кидают, и снаружи это всё вылетает, то что-то как-то не верится, что "само свернётся", таки


    Если что угодно и куда угодно летает — не свернется. Но и далеко не в любой валидной программе можно найти хоть что-нибудь, что можно доказать . А в тех программах, в которых хочется доказывать, обычно можно доказывать. Там обычно достаточно дисциплины присутствует, чтобы "частные доказательства" как раз работали.

    M>>А вот как вы будете гарантировать ваше предусловие я плохо представляю.

    E>Я это уже понял. Я только не понимаю, как ты вообще можешь при этом гарантировать хоть какие-то постусловия или инварианты кода... В том смысле что эти постусловия ничем от других не отличаются вообще-то
    Я? В операционной семантике, конечно же. Ну никак без нее. Можно попробовать и формализовать (вроде функция над внешним миром, но там нужно ввести взаимодействия на этот мир, "тики" и т.п.). В общем, я предпочитаю доказывать на не слишком формальной базе, см. выше. Вполне нормально работает во всех случаях, где мне это было нужно.


    M>>Только вот в 95% случаев мы в конце концов упираемся во взаимодействие со внешним миром (файлы/сеть/пользователь), оттуда и растет большинство исключений.

    E>IMHO, это зависит от специфики задачи. Кроме того, код, который нкепосредственно с этим миром работает должен воспринимать отказ мира работать, как штатную ситуацию, и никаких исключений по этому поводу не кидать. Ну кроме там ситуаций, когда нарушины внутренние инварианты, ну там типа драйвер неадекватно работает или ещё что фатальное происходит. Но это не внешний мир чудит, а наш комп рушится просто.
    E>А если внешний мир, то адекватно это всё как-то обрабатывать и возвращать клиентскому коду. А уж клиентский код снова обрабаьывает и возвращает выше и так пока на каком-то уровне мы не решим, что это типа всё, приплыли, значит. Ну и там уже можно и исключение кинуть...

    От ситуации зависит. Вполне может оказаться, что проще всего внутри кинуть исключение, поймать его на границе библиотеки и вернуть ошибку "кодом ошибки". Все зависит от внутреннего устройства библиотеки/фрагмента кода. Если там может отказывать почти все, то проще исключением в разумных пределах.
    Re[53]: Вот еще, или я, кажется, читать разучился
    От: maxkar  
    Дата: 06.03.13 15:52
    Оценка: 3 (2) +1
    Здравствуйте, alex_public, Вы писали:

    _>Это мы же уже обсуждали вроде.) Если приложение в случае кривого конфига должно завершаться, то конечно используем исключения. А если оно просто подставляет дефолтные значения и работает дальше, то зачем они тут?

    _>Ну и соответственно если только при одном виде ошибок с конфигом завершаемся, то тогда только этот вид ошибок и обрабатываем исключениями...

    А проблема в том, что два ваших сценария на практике очень редко встречаются. Гораздо чаще встречаются другие варианты. Например, спросить пользователя о том, что же именно он хотел. В этом случае "локально" решение принять нельзя. Или вывести где-нибудь ошибку (в тех же ide окошко редактора может писать "файл такой-то недоступен" с возможностью refresh). Или, например, попробовать повторить попытку обмена с сервером (потому что пользователь решил, что загружать конфиг по http — это круто) и только после пятой попытки вернуть ошибку наверх. Ну не может ничего "парсер конфига" в этой ситуации логичного предпринять.

    Характерные особенности:
    1. Обработка ошибки нелокальна. В некоторых случаях (спросить пользователя) еще и способ обработки неизвестен.
    2. Ошибка происходит где-то в глубине "опасного" контекста (т.е. в глубине стека вызовов). Поэтому вручную проверять на каждом уровне коды возврата — неудобно.

    Сделать ли внешее API с исключениями или нет — другой вопрос. Внутри исключения точно удобны.

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

    _>В C++ я не видел общепринятой стратегии именования. Там даже потомка общего по сути нет.

    Это все не страшно. Главное, есть namespaces. Все-таки вероятность конфликта namespaces не такая большая (да и поправить их при желании, наверное, проще, чем коды ошибок по всему коду). Как-то же библиотеки и сейчас работают. Просто кодов ошибок гораздо меньше и все они в "глобальном" пространстве этих кодов.

    _>Вообще то для таких вещей есть классические решения. Типа функций GetLastError/SetLastError с буфером где-нибудь в tls.

    И для каждой библиотеки — свой буфер? А потом перебором по буферам искать, чей же это был код возврата и из какого буфера его выдирать? Это я про библиотеки в основном. Ну и запись в глобальный буфер (который элементарно затирается, если предыдущую ошибку проигнорировали) больше на решение от безисходности похоже. С исключениями "затереть" реальную ошибку сложнее. Можно, конечно, но "на ровном месте" сложнее.

    M>>Четвертый. Грамотно спроектированные исключения образуют отношения master-detail.


    _>Не очень понятно чем в этом исключения лучше. Разве что тем, что catch автоматом это отлавливает и не надо писать лишний if. Ну так и классы исключений тоже писать тогда не надо.

    Ну да, не надо писать лишний if. А может, и не один. Под одним исключением может висеть достаточно много различных детей.

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


    Практически любой ввод/вывод с разбором форматов (там несколько уровней запросто получается). Сложные семантические преобразования моделей (компиляторы какие-нибудь). Можно рассматривать как вариант предыдущего случая (когда модель "читается" в несколько приемов). Некоторые случай runtime-композиции. Когда "как обрабатывать ошибку" зависит от того, какой граф действующих объектов построен и конкретику знает только "построитель графа". Тот же проброс ошибок чтения потока, когда поток у нас абстрактный (IStream, например).

    Вот во всех этих случаях нужно смотреть, в каких пределах что удобнее (иногда и trySomething или default value бывают удобнее исключений). В основном на исключениях оказывается удобнее.

    А вот во всех остальных случаях нелокального перехода действительно нет. Но я затрудняюсь привести примеры, когда там потребовались бы коды возврата . Т.е. большая часть остального кода (не связанная со вводом/выводом) должна просто работать. И там если что-то не так, нужно глушить всю программу (для чего, опять же, исключения подходят лучше). Может, конечно, я какие-то еще сценарии забыл, но в целом все вроде бы так выходит.
    Re[33]: Вот еще, или я, кажется, читать разучился
    От: Abidos  
    Дата: 08.03.13 23:25
    Оценка:
    Здравствуйте, alex_public, Вы писали:

    _>Думаю логика работы очевидна, да? Так вот как будет выглядеть подобный код, если переписать его через исключения (их тогда бросает функция ReadProfile)? Он будет удобнее приведённого выше или нет?


    На мой взгляд, вам стоит задуматься над вашей трактовкой исключительных ситуаций.

    С моей точки зрения, в данном случае ReadProfile должен возвращать код ошибки, только если профайл не может быть прочитан из-за того, что он отсутствует — в этом случае создается новый профайл. Это не является исключительной ситуацией и правильно использовать код возврата для связывания логики.
    Если же возникло исключение файловой системы — то это исключительная ситуация. Это исключение может быть выброшено как функцией ReadProfile, так и CreateProfile. Скорее всего в таком случае и не нужно пытаться создать профайл, если при чтении возникло исключение — исключение должно быть обработано вышележащим кодом.

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