Re[16]: catch { throw; }
От: Roman Odaisky Украина  
Дата: 25.06.08 19:46
Оценка:
Здравствуйте, merk, Вы писали:

M>по моему очевидно, что покидание контекста возникновения ошибки приводит к трудности ее исправления. теряются детали. вы же утверждаете общо — что мол там перехватим где удобно! но это слишком общо.

M>я же утверждаю, что локализовать ошибку можно только где-то вблизи ее возниконовения. и даже нужно.

Наоборот, детали появляются.
void MyFile::MyFile(char const* path)
{
    m_fd = open(path, mode);
    if(m_fd < 0)
    {
        ...а, собственно, что?
    }
}

Здесь совершенно неясно, что за файл не удалось открыть, и насколько это критично.

То ли дело в пользовательском коде:
MyFile log("/var/log/myprogram/mainlog");

MyFile userPreferences(homeDir / ".config/myprogram/settings");

В пользовательском коде известно, что нужно делать в случае возникновения проблемы, а в общем — нет.
До последнего не верил в пирамиду Лебедева.
Re[3]: Что Вам мешает в С++?
От: Аноним  
Дата: 25.06.08 20:57
Оценка:
GN>После паскаля, думаю, сложно понять язык. Это ничто иное, как современный стандартизованный (кроссплатформенный) ассемблер. К сведению — традиционные ассемблеры сейчас могут переплюнуть в
выделенное — оксюморон
Re[18]: catch { throw; }
От: minorlogic Украина  
Дата: 25.06.08 21:02
Оценка: 1 (1)
Сама идея что обработать ошибку по месту удобнее — ошибочна.

Типичный пример , ошибка выделения памяти , ну как прикажешь ее локально обработать ?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[19]: catch { throw; }
От: merk Россия  
Дата: 25.06.08 21:05
Оценка:
Здравствуйте, minorlogic, Вы писали:

M>Сама идея что обработать ошибку по месту удобнее — ошибочна.


M>Типичный пример , ошибка выделения памяти , ну как прикажешь ее локально обработать ?


интересно как вы предлагаете ее обработать нелокально.
что вы будете делать если возникла такая ошибка?
Re[20]: catch { throw; }
От: minorlogic Украина  
Дата: 25.06.08 21:20
Оценка:
Здравствуйте, merk, Вы писали:

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


M>>Сама идея что обработать ошибку по месту удобнее — ошибочна.


M>>Типичный пример , ошибка выделения памяти , ну как прикажешь ее локально обработать ?


M>интересно как вы предлагаете ее обработать нелокально.

M>что вы будете делать если возникла такая ошибка?

Так и бум отвечать вопросом на вопрос?

А все просто , наверху я могу изменить параметры и попытаться снова или отказаться от операции, все зависит от программы.

Есть отличное империческое правило

"кидайте исключение если вы не можете выполнять дальнейшии операции"

напрмиер в псевдокоде.

void readHeaderFromFile(filename)
{
file f(filename);
if(f.error())
{
throw ("open file error");
}

readHeader(f);
}

или наоборот

bool readNetworkPacket(header& h)
{
readHeader(h);
return isValid(h);
}

с заголовком пакета нам делать ничего не надо , но мы можем определить является ли заголовок валидным.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[21]: catch { throw; }
От: merk Россия  
Дата: 25.06.08 22:30
Оценка: -2 :)
Здравствуйте, minorlogic, Вы писали:

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


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


M>>>Сама идея что обработать ошибку по месту удобнее — ошибочна.


M>>>Типичный пример , ошибка выделения памяти , ну как прикажешь ее локально обработать ?


M>>интересно как вы предлагаете ее обработать нелокально.

M>>что вы будете делать если возникла такая ошибка?

M>Так и бум отвечать вопросом на вопрос?


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

M>А все просто , наверху я могу изменить параметры и попытаться снова или отказаться от операции, все зависит от программы.

если у вас недостаток памяти, все ваши трепыхания ни к чему не приведут. см. совет выше.

M>Есть отличное империческое правило

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

M>напрмиер в псевдокоде.


M>void readHeaderFromFile(filename)

M>{
M> file f(filename);
M> if(f.error())
M> {
M> throw ("open file error");
M> }

M> readHeader(f);

M>}

и что? в 100 местах программы вы вызываете эту функцию.
и в ста местах программы вы будете ее писать в конструкции
try{
readHeaderFromFile(filename)
} catch ....

не утомительно?
вообще функция очевидно косорукая. любая функция может и часто должна иметь предусловия.
в вашем случае просто валидность имени файла. не пустое имя, не нуль(если указатель), правильно сформированное. это — ну например.
вы ж без проверки, тут же конструируете обьект, обламываетесь например в конструкторе, и всю кучу возможных ошибок, то есть —
невалидность имени, факт существования файла, существование файловой системы вообще, заблокированность файла кем-то другим, заблокированность файловой системы и прочие ошибки ввода вывода... завернули в исключение "ошибка открытия файла", и кинули наружу.
и уже готовы меня убедить, что сможете восстановиться от ошибки.
КАК? вы же в реальности не знаете что произошло.
если вы будете проверять предусловия(когда-нить в жизни), вы будете тоже генерить исключения??? тогда вызов каждой функции будете делать в блоке try{} что-ли??? не утомительный ли стиль?

короче. вот тут наткнулся на какое-то руководство... ну совершенно согласен с автором. особенно обратите внимание на конец страницы — 11.5. Исключения и вопросы проектирования
http://valera.asf.ru/cpp/book/c11.shtml
Re[22]: catch { throw; }
От: crable США  
Дата: 26.06.08 04:23
Оценка: +1
Здравствуйте, merk, Вы писали:

[snip]

M>>Есть отличное империческое правило

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

Так себе и представляю: сидит разработчик и думает "тут я в принципе не могу написать продолжение, а тут могу, но, мне кажется, что в принципе не могу". Кто эту разницу сможет обнаружить?

M>>напрмиер в псевдокоде.


M>>void readHeaderFromFile(filename)

M>>{
M>> file f(filename);
M>> if(f.error())
M>> {
M>> throw ("open file error");
M>> }

M>> readHeader(f);

M>>}

M>и что? в 100 местах программы вы вызываете эту функцию.

M>и в ста местах программы вы будете ее писать в конструкции
M>try{
M> readHeaderFromFile(filename)
M>} catch ....

M>не утомительно?


Утомительно, конечно, а зачем так писать? Перехватывайте исключения на более высоком уровне. В нормальных проектах try catch не так уж и часто встречаются.

M>вообще функция очевидно косорукая. любая функция может и часто должна иметь предусловия.

M>в вашем случае просто валидность имени файла. не пустое имя, не нуль(если указатель), правильно сформированное. это — ну например.

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

M>вы ж без проверки, тут же конструируете обьект, обламываетесь например в конструкторе, и всю кучу возможных ошибок, то есть —

M>невалидность имени, факт существования файла, существование файловой системы вообще, заблокированность файла кем-то другим, заблокированность файловой системы и прочие ошибки ввода вывода... завернули в исключение "ошибка открытия файла", и кинули наружу.
M>и уже готовы меня убедить, что сможете восстановиться от ошибки.
M>КАК? вы же в реальности не знаете что произошло.

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

M>если вы будете проверять предусловия(когда-нить в жизни), вы будете тоже генерить исключения??? тогда вызов каждой функции будете делать в блоке try{} что-ли??? не утомительный ли стиль?


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

[snip]
The last good thing written in C was Franz Schubert's Symphony No. 9.
Re[3]: Что Вам мешает в С++?
От: Gluk_Kazan  
Дата: 26.06.08 04:30
Оценка:
Здравствуйте, gear nuke, Вы писали:

> К сведению — традиционные ассемблеры сейчас могут переплюнуть в метапрограммировании любые шаблоны. Только писанины там будет...


LOL я то глупый думал, что макросы да шаблоны как раз предназначены для уменьшения писанины

> вот Страуструп тоже устал писать на традиционном ассемблере...


Страуструп устал дожидаться когда Simula ему курсовик сосчитает
Re[22]: catch { throw; }
От: minorlogic Украина  
Дата: 26.06.08 04:51
Оценка: +2
Здравствуйте, merk, Вы писали:

M>>void readHeaderFromFile(filename)

M>>{
M>> file f(filename);
M>> if(f.error())
M>> {
M>> throw ("open file error");
M>> }

M>> readHeader(f);

M>>}

M>и что? в 100 местах программы вы вызываете эту функцию.

M>и в ста местах программы вы будете ее писать в конструкции
M>try{
M> readHeaderFromFile(filename)
M>} catch ....

С чего ты взял что если фугкция генерит исключение то она должна сразу оборачиватся в try catch ? это неверная пердпосылка и дальнейшие рассуждения неверны.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[2]: Что Вам мешает в С++?
От: CreatorCray  
Дата: 26.06.08 07:49
Оценка: :)
Здравствуйте, gear nuke, Вы писали:

GN>Или internal compiler error — очень вразумительное сообщение об ошибке

Подобное честно говоря последний раз встречал в VC6...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Что Вам мешает в С++?
От: dip_2000 Россия  
Дата: 26.06.08 08:18
Оценка: +3
Здравствуйте, CreatorCray, Вы писали:

CC>Здравствуйте, gear nuke, Вы писали:


GN>>Или internal compiler error — очень вразумительное сообщение об ошибке

CC>Подобное честно говоря последний раз встречал в VC6...
Да, VS 2005 современно падаает
Re[23]: catch { throw; }
От: merk Россия  
Дата: 26.06.08 08:23
Оценка: -1 :)
Здравствуйте, crable, Вы писали:

C>Утомительно, конечно, а зачем так писать? Перехватывайте исключения на более высоком уровне. В нормальных проектах try catch не так уж и часто встречаются.


я спорил с утверждением, что коды возврата позволяют их игнорировать. и потому — исключения!
теперь вы советуете игнорировать исключения. точки зрения взаимоисключающие.

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

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

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

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

C>Да. Нет, а зачем? Очень утомительный, поэтому так никто не делает, исключения перехватываются на более высоком уровне. В частности, нарушение предусловий, как правило, означает ошибку в логике программы, восстановиться после нее нельзя (ну, разве, что послать письмо разработчикам, чтобы они ее пофиксили и прислали патч, произвести горячую замену кода и продолжить работу ), поэтому вполне может хватить одного обработчика, который нарисует окошко с сообщением о критическом сбое в программе и т.п.

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

C>[snip]
Re[24]: catch { throw; }
От: VoidEx  
Дата: 26.06.08 08:42
Оценка: +1
Здравствуйте, merk, Вы писали:

M>я спорил с утверждением, что коды возврата позволяют их игнорировать. и потому — исключения!

M>теперь вы советуете игнорировать исключения. точки зрения взаимоисключающие.

Вы бы не путали. Игнорирование кода возврата приведёт к неопределённому поведению, а "игнорирование" (которые сейчас вы имели в виду) исключения — ко вполне определённым последствиям.
Не надо понятия подменять. С исключениями я не могу вызвать new и получить 0 с последующим AV.
Re[25]: catch { throw; }
От: merk Россия  
Дата: 26.06.08 09:27
Оценка:
Здравствуйте, VoidEx, Вы писали:

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


M>>я спорил с утверждением, что коды возврата позволяют их игнорировать. и потому — исключения!

M>>теперь вы советуете игнорировать исключения. точки зрения взаимоисключающие.

VE>Вы бы не путали. Игнорирование кода возврата приведёт к неопределённому поведению, а "игнорирование" (которые сейчас вы имели в виду) исключения — ко вполне определённым последствиям.

VE>Не надо понятия подменять. С исключениями я не могу вызвать new и получить 0 с последующим AV.

это вам не нужно подменять понятия.
я уж сто раз говорил о неустранимых ошибках. что и должно оформляться как исключения.
ошибки эти — нарушение инвариантов непротиворечивости системы. как то — деление на нуль, недостаток памяти, нарушение предусловий и проч.
способ реакции на эти ошибки — верная диагностика и завершение работы.
прыгающие через контексты исключения как раз для этого и приспособлены.
ноль в указателе вы можете получить просто присвоением туда нуля. и исключения не будет.
что ж касается исключения в new или getmem, то по результату функции прямо видно, удалась функция или нет. наличие исключения тут в принципе некритично.
аналогично с выбором элемента их списка, хотите взять элемент, а его там нет. тоже для невозможности игнора бросать исключение, или просто проверить на не null? а если не проверить — то можно упасть? по вашей схеме НУЖНО генерить исключение. так? если не так, то почему функция взятия нечта из списка свободной памяти менеджера кучи, должна бросить исключение, а взятие элемента из другого списка — нет?
..щас будет дискуссия о добре и зле, поскольку четкого ответа на этот вопрос нет.
Re: explicit инициализация массивов
От: sokel Россия  
Дата: 26.06.08 09:43
Оценка:
мелочь конечно, но немного напрягает...

то есть можно так:

int * pa = new int[10]();
int a[10] = {};


а вот если в структуре, то только memset или цикл...

struct s
{
  s() : a(???) {  }
  int a[10];
};
Re[23]: catch { throw; }
От: Erop Россия  
Дата: 26.06.08 10:13
Оценка: 2 (2) +2
Здравствуйте, crable, Вы писали:

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


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

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

Так обычно строят обработку исключительных ситуаций на исключениях. Есть стратегии делать то же на кодах возврата. IMHO они хуже, но тоже есть, и так тоже можно писать. Но тогда таки нужны примеры, и, хотя бы, изложения способа обработки имключительных ситуаций в программе в целом, а то не о чём разговор выходит
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[26]: catch { throw; }
От: VoidEx  
Дата: 26.06.08 10:22
Оценка: +1
Здравствуйте, merk, Вы писали:

M>это вам не нужно подменять понятия.


Не надо только детский сад устраивать.

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

Особенно если взять ваш же аргмент

и в ста местах программы вы будете ее писать в конструкции
try{
readHeaderFromFile(filename)
} catch ....

не утомительно?


При том что if (!readHeaderFromFile(filename)) { ... } почему-то не утомительно, так и говорить даже не о чем.
Re[26]: catch { throw; }
От: Аноним  
Дата: 26.06.08 10:33
Оценка: +3
Здравствуйте, merk, Вы писали:

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



M>..щас будет дискуссия о добре и зле, поскольку четкого ответа на этот вопрос нет.


Как раз есть, просто вы этот ответ упорно не хотите принимать. У меня складывается впечатление, что у вас совершенно не правильное представление о том, для чего в C++ предназначены исключения. C++ exceptions — это лишь средство для сообщения об ошибках, а не о каких то исключительных ситуациях. Это замена кодам возврата. Произошла ошибка в программе — сгенерировали исключение и всё. Зачем усложнять? О том, что считать ошибкой, а что нет, можно почитать например у Саттера (да и Мейерс об этом вроде писАл тоже).
Внутри одно проекта (или хотябы модуля) необходимо определить какой подход к обработке ошибок использовать: основаный на исключениях либо на кодах возврата и строго его придерживаться. А что касается спора по поводу использования кодов возврата либо исключений — дык он уже давно завершился (не в пользу кодов возврата).
Re: Что Вам мешает в С++?
От: Аноним  
Дата: 26.06.08 10:34
Оценка:
Здравствуйте, remark, Вы писали:

R>Что Вам мешает в С++?


Все замечательно, когда мы пишем код сами, но самое веселое начинается, когда нужно использовать/интегрировать проекты соседнего отдела. Тут сказывается плохая поддержка компонентной модели, решено кажется везде где можно, Common Lisp, OCaml, Java, .NET.
Re[27]: catch { throw; }
От: merk Россия  
Дата: 26.06.08 10:39
Оценка: -2 :))
Здравствуйте, VoidEx, Вы писали:

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


M>>это вам не нужно подменять понятия.


VE>Не надо только детский сад устраивать.


VE>С Вами скучно спорить, аргументов серьёзных нет, а доказывать что-то Вам лично я не хочу.


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