Re[2]: Какие у исключений проблемы?
От: vsb Казахстан  
Дата: 04.11.14 20:37
Оценка:
Здравствуйте, AlexRK, Вы писали:

vsb>>Какие есть серьёзные аргументы против исключений и за (извиняюсь за каламбур) возврат к кодам возврата? Ведь это же ужасный код, когда после вызова каждой функции мы тут же проверяем err и если он не null, просто передаём его наверх. Это то, от чего избавляют исключения.


ARK>Главная проблема в том, что исключения создают дополнительный скрытый поток управления, который никак в коде не виден.


ARK>Это не было бы проблемой, если бы гарантировалась атомарность всех изменений на некотором участке, на котором предположительно может вылететь исключение. То есть, если исключения нет — коммит, если есть — роллбек. При таком раскладе программа всегда остается в валидном состоянии и все инварианты сохраняются в любой момент времени. Увы, у STM есть фундаментальная проблема — ввод-вывод (на данный момент приемлемого решения этой проблемы не найдено).


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

ARK>Коды возврата гарантируют видимость всех путей исполнения и отсутствие неожиданных нарушений инвариантов, но генерируют много бойлерплейта.
ARK>Что лучше — хрен знает.

По-моему невалидное состояние после исключения это достаточно редкая штука. Можете привести какие то часто встречающиеся случаи таких состояний в managed языке (Java/C# например)? Я только искусственные примеры могу придумать, в реальности я такого не видел (может не замечал).
Отредактировано 04.11.2014 20:37 vsb . Предыдущая версия .
Re[2]: Какие у исключений проблемы?
От: vsb Казахстан  
Дата: 04.11.14 20:40
Оценка:
Здравствуйте, smeeld, Вы писали:

vsb>>Какие есть серьёзные аргументы против исключений и за (извиняюсь за каламбур) возврат к кодам возврата? Ведь это же ужасный код, когда после вызова каждой функции мы тут же проверяем err и если он не null, просто передаём его наверх. Это то, от чего избавляют исключения.


S>Исключения это очень медленно и размашисто, по сравнению с if(func()!=0) err();

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

Насколько медленней? Насколько это может сказаться в работе программы? Я вот не могу себе представить сценария, где программа будет пытаться миллион раз открыть несуществующий файл и её производительность будет страдать от медленных исключений.
Re[3]: Какие у исключений проблемы?
От: AlexRK  
Дата: 04.11.14 20:48
Оценка:
Здравствуйте, x-code, Вы писали:

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


Да, что делать — непонятно. Монады разве что действительно прикручивать.

XC>Например, сделать какой-то особый оператор (вместо throw) который был бы чем-то средним между throw и return: он мог бы бросать исключение, если ранее в какой-то глобальной таблице блок try выставил флаг, что данный тип исключения обрабатывается; а если флага нет, то возвращал бы свой аргумент как код возврата.


Как-то слишком запутанно получается.
Re[3]: Какие у исключений проблемы?
От: AlexRK  
Дата: 04.11.14 20:52
Оценка: +1
Здравствуйте, vsb, Вы писали:

vsb>По-моему невалидное состояние после исключения это достаточно редкая штука. Можете привести какие то часто встречающиеся случаи таких состояний в managed языке (Java/C# например)? Я только искусственные примеры могу придумать, в реальности я такого не видел (может не замечал).


Я бы сказал, что это не только не редкая штука, а наоборот — повсеместная.
Любой метод, изменивший некоторое поле класса и после этого выкинувший исключение, уже оставил объект в промежуточном состоянии.
Другой вопрос — всегда ли это приводит к катастрофическим последствиям? Понятное дело, что нет.
Re[4]: Какие у исключений проблемы?
От: WolfHound  
Дата: 04.11.14 20:55
Оценка: 13 (4) +5
Здравствуйте, smeeld, Вы писали:

S>"Правильно реализованные", это как? Смотрел как они реализованы в ELF+gcc/clang/solarisstudio.

Вот так:

The second scheme, and the one implemented in many production-quality C++ compilers, is a table-driven approach. This creates static tables at compile time and link time that relate ranges of the program counter to the program state with respect to exception handling.[18] Then, if an exception is thrown, the runtime system looks up the current instruction location in the tables and determines what handlers are in play and what needs to be done. This approach minimizes executive overhead for the case where an exception is not thrown. This happens at the cost of some space, but this space can be allocated into read-only, special-purpose data sections that are not loaded or relocated until an exception is actually thrown.


S>Простой if(err) return -1; сработает на порядок быстрее, чем throw x; }catch(){...}

Ты что при каждом вызове функции исключение выбрасываешь?
Обычно они летают редко. И когда не летают, вообще никаких дополнительных расходов нет.
При этом проверка кодов возврата тормозит всегда.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Какие у исключений проблемы?
От: AlexRK  
Дата: 04.11.14 20:57
Оценка: +1 :))
Здравствуйте, vsb, Вы писали:

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


Тут как всегда — кто о чем, а сиплюсплюсник о скорости. Корректность ПО, производительность разработки? Не, не слышал.

Насчет замедления я где-то читал постмортем о разработке игры для PS3, там чувак приводил цифры насчет исключений — по его словам, замедление может быть до 30% (поэтому они от исключений отказались).
Но это, понятное дело, на слабоватом железе.
Re[3]: Какие у исключений проблемы?
От: smeeld  
Дата: 04.11.14 20:58
Оценка: +1
Здравствуйте, vsb, Вы писали:


vsb>Насколько медленней?


А это уже зависит от стечения обстоятельств.
C медленней на порядок это, конечно, перебульонил малость,
но в остальном происходит поиск по нескольким массивам в секциях,
отмаппенного в память процесса, объектника: в .eh_frame ищутся CIE для
нахождения FDE, из FDE попадаем в секцию расширение (.gcc_except_table для gcc)
с массивом LSDA структур, по ним находим пойнтеры к type_info вызовом функции personality,
которая своя для каждого языка. type_info находятся в другой секции, при совпадении, находим
в массивах call site-ов из текущего LSDA пойнтеры для landing pad.
Соответствующими значениями из call site-ов заполняется структура Unwind_Context, далее происходит
вторая фаза, при которой всё повторяется сначала, только не для поиска совпадений,
а очищения фреймов стека вызовом той же personality. После чего управление передаётся на обработку загрузкой
оформленного контекста. В инете полно инфы, описал тут так для того, чтоб масштаб событий, происходящих после throw, был заметен.
Re[4]: Какие у исключений проблемы?
От: vsb Казахстан  
Дата: 04.11.14 20:59
Оценка: +1
Здравствуйте, AlexRK, Вы писали:

vsb>>По-моему невалидное состояние после исключения это достаточно редкая штука. Можете привести какие то часто встречающиеся случаи таких состояний в managed языке (Java/C# например)? Я только искусственные примеры могу придумать, в реальности я такого не видел (может не замечал).


ARK>Я бы сказал, что это не только не редкая штука, а наоборот — повсеместная.

ARK>Любой метод, изменивший некоторое поле класса и после этого выкинувший исключение, уже оставил объект в промежуточном состоянии.
ARK>Другой вопрос — всегда ли это приводит к катастрофическим последствиям? Понятное дело, что нет.

Интересно, я неявно стараюсь все изменения записывать в локальные переменные и присваивать в поля скопом, уже когда вся работа выполнена, а присваивания уж точно не выкинут исключение. Да, есть такая проблема и нужно писать exception-safe код. Вопрос — сложно ли это?
Re[5]: Какие у исключений проблемы?
От: smeeld  
Дата: 04.11.14 21:01
Оценка: -5 :)
Здравствуйте, WolfHound, Вы писали:

WH>

WH>The second scheme, and the one implemented in many production-quality C++ compilers, is a table-driven approach. This creates static tables at compile time and link time that relate ranges of the program counter to the program state with respect to exception handling.[18] Then, if an exception is thrown, the runtime system looks up the current instruction location in the tables and determines what handlers are in play and what needs to be done. This approach minimizes executive overhead for the case where an exception is not thrown. This happens at the cost of some space, but this space can be allocated into read-only, special-purpose data sections that are not loaded or relocated until an exception is actually thrown.


Всякие статейки в инетах читаем? Похвально, но посоветовл бы заглянуть в реальные
исходники, и узреть как оно на самом деле там наворочено.
Re[6]: Какие у исключений проблемы?
От: WolfHound  
Дата: 04.11.14 21:06
Оценка: -2
Здравствуйте, smeeld, Вы писали:

S>Всякие статейки в инетах читаем? Похвально, но посоветовл бы заглянуть в реальные

S>исходники, и узреть как оно на самом деле там наворочено.
Я реально измерял производительность.
Коды возврата слили.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: Какие у исключений проблемы?
От: AlexRK  
Дата: 04.11.14 21:07
Оценка: +1
Здравствуйте, vsb, Вы писали:

vsb>Интересно, я неявно стараюсь все изменения записывать в локальные переменные и присваивать в поля скопом, уже когда вся работа выполнена, а присваивания уж точно не выкинут исключение. Да, есть такая проблема и нужно писать exception-safe код. Вопрос — сложно ли это?


Writing exception-safe code is really hard
Re[7]: Какие у исключений проблемы?
От: smeeld  
Дата: 04.11.14 21:18
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Я реально измерял производительность.

WH>Коды возврата слили.

Молодец. Только у меня имеются противоположные результаты. Может
просто дизассемблером по бинарникам и по исходникам компиляторов прошвырнёмся,
и определим, что будет исполнятся медленней, а что быстрее.
Re[8]: Какие у исключений проблемы?
От: WolfHound  
Дата: 04.11.14 21:27
Оценка:
Здравствуйте, smeeld, Вы писали:

S>Молодец. Только у меня имеются противоположные результаты. Может

S>просто дизассемблером по бинарникам и по исходникам компиляторов прошвырнёмся,
S>и определим, что будет исполнятся медленней, а что быстрее.
Покажи класс. Я скажу, где у тебя ошибка.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: Какие у исключений проблемы?
От: LaptevVV Россия  
Дата: 04.11.14 21:43
Оценка:
Сугубое ИМХО.
Одна из серьезных проблем, которую практически не поминают — это парадигма обработки исключений.
По сути это событийное программирование.
Ведь исключения могут генерироваться в проге где угодно.
И обработка их ведется совершенно в другом месте. Причем программист этим практически не управлял.
И вот получается, что в одной проге смешаны как минимум две, а то и три парадигмы: ООП+событийное (и очень часто процедурное).

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

Надо отметить, что в новом стандарте управляемость исключений СУЩЕСТВЕННО улучшилась.
Текущее исключение можно явным образом сохранить, передать в нужную функцию, заново кинуть в нужном месте.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[9]: Какие у исключений проблемы?
От: smeeld  
Дата: 04.11.14 22:09
Оценка: +1 :))
Здравствуйте, WolfHound, Вы писали:

WH>Покажи класс. Я скажу, где у тебя ошибка.


Ок. Код, обрабатывающий ошибку возвратом из функции:
Такой кодик
#include <iostream>

int func(int a){
int b=0;
if(a) b=-1;
return b;
};

int main(){

 int a=10;

if( func(a)!=0) std::cout<<"BAD \n";
else std::cout<<" Ok \n";
};

компилится сюда

00000000004007a0 <_Z4funci>:
  4007a0:       55                      push   %rbp
  4007a1:       48 89 e5                mov    %rsp,%rbp
  4007a4:       89 7d ec                mov    %edi,-0x14(%rbp)
  4007a7:       c7 45 fc 00 00 00 00    movl   $0x0,-0x4(%rbp)
  4007ae:       83 7d ec 00             cmpl   $0x0,-0x14(%rbp)
  4007b2:       74 07                   je     4007bb <_Z4funci+0x1b>
  4007b4:       c7 45 fc ff ff ff ff    movl   $0xffffffff,-0x4(%rbp)
  4007bb:       8b 45 fc                mov    -0x4(%rbp),%eax
  4007be:       5d                      pop    %rbp
  4007bf:       c3                      retq   

00000000004007c0 <main>:
  4007c0:       55                      push   %rbp
  4007c1:       48 89 e5                mov    %rsp,%rbp
  4007c4:       48 83 ec 10             sub    $0x10,%rsp
  4007c8:       c7 45 fc 0a 00 00 00    movl   $0xa,-0x4(%rbp)
  4007cf:       8b 45 fc                mov    -0x4(%rbp),%eax
  4007d2:       89 c7                   mov    %eax,%edi
  4007d4:       e8 c7 ff ff ff          callq  4007a0 <_Z4funci>
  4007d9:       85 c0                   test   %eax,%eax
  4007db:       0f 95 c0                setne  %al
  4007de:       84 c0                   test   %al,%al
  4007e0:       74 11                   je     4007f3 <main+0x33>
  4007e2:       be f0 08 40 00          mov    $0x4008f0,%esi
  4007e7:       bf 60 10 60 00          mov    $0x601060,%edi
  4007ec:       e8 af fe ff ff          callq  4006a0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
  4007f1:       eb 0f                   jmp    400802 <main+0x42>
  4007f3:       be f6 08 40 00          mov    $0x4008f6,%esi
  4007f8:       bf 60 10 60 00          mov    $0x601060,%edi
  4007fd:       e8 9e fe ff ff          callq  4006a0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
  400802:       b8 00 00 00 00          mov    $0x0,%eax
  400807:       c9                      leaveq 
  400808:       c3                      retq


А такой
#include <iostream>

void func(int a){
int b=0;
if(a) throw 1;
throw 2;
};

int main(){

 int a=10;
try{
 func(a);
 }catch(int s)
   {
    if(s==1) std::cout<<" Ok \n";
     else std::cout<<" BAD \n";
  };
};


Сюда

0000000000400a20 <_Z4funci>:
  400a20:       55                      push   %rbp
  400a21:       48 89 e5                mov    %rsp,%rbp
  400a24:       48 83 ec 20             sub    $0x20,%rsp
  400a28:       89 7d ec                mov    %edi,-0x14(%rbp)
  400a2b:       c7 45 fc 00 00 00 00    movl   $0x0,-0x4(%rbp)
  400a32:       83 7d ec 00             cmpl   $0x0,-0x14(%rbp)
  400a36:       74 22                   je     400a5a <_Z4funci+0x3a>
  400a38:       bf 04 00 00 00          mov    $0x4,%edi
  400a3d:       e8 8e fe ff ff          callq  4008d0 <__cxa_allocate_exception@plt>
  400a42:       c7 00 01 00 00 00       movl   $0x1,(%rax)
  400a48:       ba 00 00 00 00          mov    $0x0,%edx
  400a4d:       be a0 21 60 00          mov    $0x6021a0,%esi
   400a52:       48 89 c7                mov    %rax,%rdi
  400a55:       e8 86 fe ff ff          callq  4008e0 <__cxa_throw@plt>
  400a5a:       bf 04 00 00 00          mov    $0x4,%edi
  400a5f:       e8 6c fe ff ff          callq  4008d0 <__cxa_allocate_exception@plt>
  400a64:       c7 00 02 00 00 00       movl   $0x2,(%rax)
  400a6a:       ba 00 00 00 00          mov    $0x0,%edx
  400a6f:       be a0 21 60 00          mov    $0x6021a0,%esi
  400a74:       48 89 c7                mov    %rax,%rdi
  400a77:       e8 64 fe ff ff          callq  4008e0 <__cxa_throw@plt>

0000000000400a7c <main>:
  400a7c:       55                      push   %rbp
  400a7d:       48 89 e5                mov    %rsp,%rbp
  400a80:       53                      push   %rbx
   400a81:       48 83 ec 18             sub    $0x18,%rsp
  400a85:       c7 45 ec 0a 00 00 00    movl   $0xa,-0x14(%rbp)
  400a8c:       8b 45 ec                mov    -0x14(%rbp),%eax
  400a8f:       89 c7                   mov    %eax,%edi
  400a91:       e8 8a ff ff ff          callq  400a20 <_Z4funci>
  400a96:       b8 00 00 00 00          mov    $0x0,%eax
  400a9b:       eb 5b                   jmp    400af8 <main+0x7c>
  400a9d:       48 89 c3                mov    %rax,%rbx
  400aa0:       e8 4b fe ff ff          callq  4008f0 <__cxa_end_catch@plt>
  400aa5:       48 89 d8                mov    %rbx,%rax
  400aa8:       48 89 c7                mov    %rax,%rdi
  400aab:       e8 70 fe ff ff          callq  400920 <_Unwind_Resume@plt>
  400ab0:       48 83 fa 01             cmp    $0x1,%rdx
  400ab4:       74 08                   je     400abe <main+0x42>
  400ab6:       48 89 c7                mov    %rax,%rdi
  400ab9:       e8 62 fe ff ff          callq  400920 <_Unwind_Resume@plt>
  400abe:       48 89 c7                mov    %rax,%rdi
  400ac1:       e8 3a fe ff ff          callq  400900 <__cxa_begin_catch@plt>
  400ac6:       8b 00                   mov    (%rax),%eax
  400ac8:       89 45 e8                mov    %eax,-0x18(%rbp)
  400acb:       83 7d e8 01             cmpl   $0x1,-0x18(%rbp)
  400acf:       75 11                   jne    400ae2 <main+0x66>
  400ad1:       be f0 0b 40 00          mov    $0x400bf0,%esi
  400ad6:       bf 80 20 60 00          mov    $0x602080,%edi
  400adb:       e8 e0 fd ff ff          callq  4008c0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
  400ae0:       eb 0f                   jmp    400af1 <main+0x75>
  400ae2:       be f6 0b 40 00          mov    $0x400bf6,%esi
  400ae7:       bf 80 20 60 00          mov    $0x602080,%edi
  400aec:       e8 cf fd ff ff          callq  4008c0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
  400af1:       e8 fa fd ff ff          callq  4008f0 <__cxa_end_catch@plt>
  400af6:       eb 9e                   jmp    400a96 <main+0x1a>
  400af8:       48 83 c4 18             add    $0x18,%rsp
  400afc:       5b                      pop    %rbx
  400afd:       5d                      pop    %rbp
  400afe:       c3                      retq


Между двумя листингами есть только одно существенное отличие- вызов функции __cxa_throw(), в коде с исключениями,
который происходит после подготовки работы функцией __cxa_allocate_exception. Эти функции
принадлежат libstdc++. __cxa_throw -это просто кроличья нора, куда проваливаемся по самое не балуйся.
Дальше приведу ссылки на исходники GCC-С++, где расписаны основные функции, в которые, так или иначе, попадает управление после вызова __cxa_throw.
Кстати, из последней мы не возвращаемся, а, загрузкой контекста стекового фрейма, оказываемся на том месте, которые сответствуют
определённым catch. В какой псоледовательности происходит вся работа можно отследить отладчиком, стартуя c break point __cxa_throw.
Ссыли

L1
L2
L3
L4
L5
Re[10]: Какие у исключений проблемы?
От: WolfHound  
Дата: 04.11.14 22:19
Оценка: +2
Здравствуйте, smeeld, Вы писали:

S>Ок. Код, обрабатывающий ошибку возвратом из функции:

Зевая. Перечитай вторую половину сообщения 10 раз.
Re[4]: Какие у исключений проблемы?
Автор: WolfHound
Дата: 04.11.14


Ты не первый и даже не десятый кто пытается доказать что-то не корректными тестами.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[11]: Какие у исключений проблемы?
От: smeeld  
Дата: 04.11.14 22:34
Оценка: :)))
Здравствуйте, WolfHound, Вы писали:


WH> Перечитай вторую половину сообщения 10 раз.


Во первых процетирую ТС

Какие есть серьёзные аргументы против исключений и за (извиняюсь за каламбур) возврат к кодам возврата? Ведь это же ужасный код, когда после вызова каждой функции мы тут же проверяем err и если он не null, просто передаём его наверх. Это то, от чего избавляют исключения.


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

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


WH>Ты не первый и даже не десятый кто пытается доказать что-то не корректными тестами.


А тестами можете размахивать на праздных академических симпозиумах и конференциях.
При разработки кода для дикого и ответственного продакшена, ориентироваться надо
на тонкое знание реализации тех или иных используемых систем, по которому определять характер
использования этих систем.
Re[12]: Какие у исключений проблемы?
От: WolfHound  
Дата: 04.11.14 23:09
Оценка: 4 (1) +4 :)
Здравствуйте, smeeld, Вы писали:

S>А тестами можете размахивать на праздных академических симпозиумах и конференциях.

S>При разработки кода для дикого и ответственного продакшена, ориентироваться надо
S>на тонкое знание реализации тех или иных используемых систем, по которому определять характер
S>использования этих систем.
Главное при этом не забыть, что в 99.999% случаев код возврата содержит значение "всё хорошо".
А значит на практике всё то чем ты тут размахиваешь просто тает на фоне постоянных if (errorcode != ok)...
Что бы получить реалистичный тест сделай пять функций, которые друг друга вызывают. Запрети компилятору их инлайнить.
Вызови их 100000 раз. А на 100001 скажи, что всё плохо.
И сравни время выполнения.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: Какие у исключений проблемы?
От: jazzer Россия Skype: enerjazzer
Дата: 05.11.14 01:22
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Интересно, я неявно стараюсь все изменения записывать в локальные переменные и присваивать в поля скопом, уже когда вся работа выполнена, а присваивания уж точно не выкинут исключение. Да, есть такая проблема и нужно писать exception-safe код. Вопрос — сложно ли это?


Я тоже так пишу. Саттер/Абрахамс в свое время прочистили мозги на этот счет.
Надо только помнить, что есть 3 уровня безопасности по исключениям.
Базовую гарантию (отсутствие утечек памяти, незакрытых хэндлов, неразлоченных мьютексов) обеспечить можно практически всегда.
Сильную — не всегда (если принимать во внимание сопутствующие накладные расходы, которые могут быть слишком большими), но и не всегда это так уж нужно.

Ну и у меня уровень exception safety, обеспечиваемый функцией — это отдельная строчка в Doxygen-комментарии перед ней, наряду с thread safety (даже макрос специальный для Doxygen есть).
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]: Какие у исключений проблемы?
От: jazzer Россия Skype: enerjazzer
Дата: 05.11.14 01:28
Оценка:
Здравствуйте, x-code, Вы писали:

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


ARK>>Главная проблема в том, что исключения создают дополнительный скрытый поток управления, который никак в коде не виден.


XC>Да, согласен.

XC>Вызываешь функцию, и не знаешь — возвратится ли она здесь или где-то вообще неизвестно где...

Ну конкретно в C++ (начиная с С++11) есть оператор nothrow(выражение), который позволяет определить, может ли выражение внутри него бросить исключение (основываясь на декларации nothrow).
К сожалению, нельзя им пометить блок кода и как-то заставить бросать ошибку компиляции, если встретилось выражение, которое может бросить, но и то хлеб — потенциально опасные функции можно проверить на nothrow заранее (полезно в шаблонах, когда не знаешь, что тебе подсунут).
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.