Сабж навеян топиком "Как это сделать" из форума по С++.
Началось все с того, что Юнусов Булат сказал:
atoi в серьезных прогах вообще лучше не использовать - при невозможности конвертации она ексепшенсы не
отбрасывает, другими словами прога будет работать до первой неудачной конвертации - потом начнет
выдавать крутой бред.
С чем я полностью согласен.
На это Vladik ответил , что
Ненавижу эксепшины. (На мой взгляд слабый аргумент)
atoi просто тихо вернет 0. А если я эксепшин в нужном месте не отловлю - тогда да, действительно будет весело.
Но собственно дело конечно же не в atoi (вернее не только в atoi). Дело в принципе — использовать, или не использовать исключения (ну или коды возврата)?
На мой вгляд глупо было бы отдавать предпочтение либо только исключениям, либо только кодам возврата, ибо назначение у этих двух механизмов несколько разное.
Я конечно не открою америку, если скажу, что коды возврата следует использовать тогда, когда есть готовый вариант поведения или готовая реакция на некоторое нестандартное событие. Ну например неправильный ввод данных. Можно спокойно проигнорировать некорректные данные, заменив их чем-то осмысленным(конечно если это допустимый вариант поведения), можно оповестить об этом пользователя и попросить его повторить ввод. Исключения для этого вовсе не обязательны. Главное — чтобы была возможность распознать некорректность данных на нужном этапе (в случае с пресловутой atoi сделать это без дополнительных усилий нельзя), и выбрать нужный вариант поведения.
Теперь рассмотрим такую ситуацию:
Идет формирование некоторой сложной модели, которая весьма чувствительна к корректности исходных данных (любое несоответствие делает дальнейшую работу ненужной). Зачем мне в куче мест вставлять проверки на значения кодов возврата сервисных функций, после чего просто говорить return? Да делать это еще по всему дереву вызовов? Не проще ли выкинуть исключение из этой сервисной функции, и поймать его на верхнем уровне?
ИМХО код будет несколько проще и понятнее.
Ну так вот, а что думает общественность по этому поводу?
Как мне уже сказали, у меня найдется множество аппонентов
Надеюсь, что и сторонников будет не меньше
И все-таки эксепшены. Аргументы: информативно, удобно, читабельно. Особенно это актуально при COM разработке — очень часто одного кода возврата бывает мало, более того большинство просто возвращает E_FAIL про который вообще ничего нельзя сказать.
А по поводу:
"Ненавижу эксепшины. (На мой взгляд слабый аргумент)
atoi просто тихо вернет 0. А если я эксепшин в нужном месте не отловлю — тогда да, действительно будет весело"
могу сказать следующее: если ты этот тихий ноль не отловишь, то проблем будет не меньше.
Иногда ИМХО удобнее сочетать оба способа
А с проверкой кода ошибки можно поступить следующим образом:
Поиметь легкий класс вокруг enum ошибок. В класса есть дополнительный флаг — "проверенно" ( мин нет, Сапер Сидоров ) Оператор равенства ( и неравенства заодно ) сбрасывает этот флаг. В деструкторе имеется проверка на наличие ошибки ( код ошибки != ОК ) и взведенного флага ( не проверил, скотина! ) и там выбрасывать исключение или поставить assert. Т.к. для клиента класса данная обертка будет прозрачна ( в смысле, тоже самое что и enum ) то потом ( после отладки итд ) его можно будет просто заменить на этот самный enum.
Т.е. как это выглядит в коде:
( пример применения )
class MyClass {
public:
enum Results
{
RES_UNKNOWN = 1,
RES_ERROR1,
RES_FATALERROR,
RES_MINDBLOWNERROR,
RES_MAX
};
static const ResultTable results[ RES_MAX ];
typedef ResultClass< results, Results > Result;
//
Result SomeMethod()
{
if ( bad_bad ) {
return RES_ERROR1;
}
return OK;
}
};
....
MyClass obj;
if ( obj.SomeMethod() != OK ) .... /// тут все будет ок
...
obj.SomeMethod(); /// а тут при возврате кода ошибки отличного от ОК, произойдет assert
Система, конечно, не без недостатков, но вдруг кому-то понадобится...
Здравствуйте Юнусов Булат, Вы писали:
ЮБ>Здравствуйте Bell, Вы писали:
ЮБ>Время все уже расставило по своим местам. ЮБ>Народ потянулся в дотнет — тама ексепшенсы рулят.
Здравствуйте Torero2002, Вы писали:
T>И все-таки эксепшены. Аргументы: информативно, удобно, читабельно. Особенно это актуально при COM разработке — очень часто одного кода возврата бывает мало, более того большинство просто возвращает E_FAIL про который вообще ничего нельзя сказать.
Так-так, нужно сюда Влада позвать. Он подробно расскажет, почему эксепшены в COM'е — это плохое решение. А коды возврата к делу не имеют никакого отношения — никто не мешает надефайнить кучу своих кодов возврата (что, кстати, придется делать и при использовании эксепшенов).
T>А по поводу:
T>"Ненавижу эксепшины. (На мой взгляд слабый аргумент) T>atoi просто тихо вернет 0. А если я эксепшин в нужном месте не отловлю — тогда да, действительно будет весело"
T>могу сказать следующее: если ты этот тихий ноль не отловишь, то проблем будет не меньше.
Сильно зависит от задачи.
Мое личное мнение — эксепшены хороши в клиентском коде. В серверном коде (и особенно в COM-серверах) им не место.
MS понятие растяжимое. Это советует конкретный сотрудник. И надо всегда относиться к этому с оглядкой.
Вот смотри. Это тот пример который он привел
public static void Main(string[] args){
int j = 0;
for(int i = 0; i < 10000; i++){
try{
j = i;
throw new System.Exception();
} catch {}
}
System.Console.Write(j);
return;
}
А это моя переделка, ибо то что он предлагает оценивать на глаз, та еще с таким малым количеством итераций это поленйший маразм.
public static void Main(string[] args){
int j = 0;
int st;
//Подождем чтобы система устаканилась после загрузки
System.Threading.Thread.Sleep(1000);
st = Environment.TickCount;
for(int i = 0; i < 1000000; i++){
try{
j = i;
throw new System.Exception();
} catch {}
}
Console.WriteLine((double)(Environment.TickCount-st)/1000000+" ms per cycle");
}
Результат выполения на средненькой по нынешним временам машинке (Celeron 1000) дает такой результат
0,015993 ms per cycle
Т.е. на вызов одного эксепшена вместе с присваиванием уходит меньше двух стотысячных секунды. И это он называет "tremendous overhead"? Даже не смешно. Чтобы это почувствовать надо генерить десятки тысяч эксепшенов в секунду.
Здравствуйте Lexey, Вы писали:
L>Так-так, нужно сюда Влада позвать. Он подробно расскажет, почему эксепшены в COM'е — это плохое решение. А коды возврата к делу не имеют никакого отношения — никто не мешает надефайнить кучу своих кодов возврата (что, кстати, придется делать и при использовании эксепшенов).
Можно подробнее — что я должен дефайнить при использовании исключений?
... L>Сильно зависит от задачи.
Естественно. О чем я и говорил. Если есть допустимый вариант поведения при (возможном) возникновении некоторой нестандартной ситуации — значит это не исключительная ситуация.
L>Мое личное мнение — эксепшены хороши в клиентском коде. В серверном коде (и особенно в COM-серверах) им не место.
А вот в CORBA зачем-то предусмотрены механизмы выброса исключений из серверов и последующей их обработки на клиентах...
Здравствуйте Bell, Вы писали:
L>>Так-так, нужно сюда Влада позвать. Он подробно расскажет, почему эксепшены в COM'е — это плохое решение.
Ой, нужно.
L>>А коды возврата к делу не имеют никакого отношения — никто не мешает надефайнить кучу своих кодов возврата (что, кстати, придется делать и при использовании эксепшенов). B>Можно подробнее — что я должен дефайнить при использовании исключений?
Способы передать информацию об ошибке. Либо однотипный класс исключения и куча кодов возврата, либо куча классов исключения.
L>>Мое личное мнение — эксепшены хороши в клиентском коде. В серверном коде (и особенно в COM-серверах) им не место.
B>А вот в CORBA зачем-то предусмотрены механизмы выброса исключений из серверов и последующей их обработки на клиентах...
Да. И еще нет никого другого способа обработать ошибку в конструкторе класса. Но просто-напросто все ошибки компилятора, которые я встречал в 6-ке, были связаны с обработкой исключений.
Здравствуйте Lexey, Вы писали:
L>Здравствуйте Torero2002, Вы писали:
T>>И все-таки эксепшены. Аргументы: информативно, удобно, читабельно. Особенно это актуально при COM разработке — очень часто одного кода возврата бывает мало, более того большинство просто возвращает E_FAIL про который вообще ничего нельзя сказать.
L>Так-так, нужно сюда Влада позвать. Он подробно расскажет, почему эксепшены в COM'е — это плохое решение. А коды возврата к делу не имеют никакого отношения — никто не мешает надефайнить кучу своих кодов возврата (что, кстати, придется делать и при использовании эксепшенов).
Коды возврата в COM, на мой взгляд, значит примерно одно тоже: либо ты послан, либо нет. Ведь не даром "умные дядьки" из Microsoft и в comdef.h и в ATL ввели интерфейсы/классы поддержки COM исключений. Хотя послушать аргументы в пользу использования кодов возврата в COM я бы послушал.
T>>А по поводу:
T>>"Ненавижу эксепшины. (На мой взгляд слабый аргумент) T>>atoi просто тихо вернет 0. А если я эксепшин в нужном месте не отловлю — тогда да, действительно будет весело"
T>>могу сказать следующее: если ты этот тихий ноль не отловишь, то проблем будет не меньше.
L>Сильно зависит от задачи.
L>Мое личное мнение — эксепшены хороши в клиентском коде. В серверном коде (и особенно в COM-серверах) им не место.
Здравствуйте George Seryakov, Вы писали:
GS>Здравствуйте Bell, Вы писали:
L>>>Так-так, нужно сюда Влада позвать. Он подробно расскажет, почему эксепшены в COM'е — это плохое решение.
GS> Ой, нужно.
С СОМ я практически не работаю, но аргументированное мнение выслушать всегда готов. Кто знает, может и сгодится в будущем...
GS> Способы передать информацию об ошибке. Либо однотипный класс исключения и куча кодов возврата, либо куча классов исключения.
Ладно, это была просто придирка
От этого никуда не деться — информацию об ошибке все равно нужно передавать. Либо код возврата, либо тип исключения, либо некоторая их комбинация.
Но главное все-таки не способ представления информации об ошибке, а способ передачи этой информации.
Как я уже говорил — я не призываю всех отказаться от использования кодов возврата, и начать использовать только исключения. Это просто глупо. Главное — грамотно разобраться где использовать исключение, а где обработать код возврата. ИМХО такой код проще
чем если бы мне пришлось проверять код возврата после вызова каждой функции, и потом просто передавать его (при наличии ошибки конечно) вверх.
В данном случае использование исключений существенно упрощают код, освобождая его от множества однотипных проверок.
Так же просто можно придумать пример, в котором использование исключений ведет к усложнению и снижению эффективности.
ИМХО главное — это хорошенько подумать, а не говорить "не люблю я исключения (коды возврата), поэтому не буду их использовать". Именно это я и хотел сказать с самого начала
GS> Да. И еще нет никого другого способа обработать ошибку в конструкторе класса. Но просто-напросто все ошибки компилятора, которые я встречал в 6-ке, были связаны с обработкой исключений.
Ну так у ж и все? Ошибок, связанных с использованием шаблонов тоже хватает. Однако это не повод отказаться от их использования... Хотя это (наличие ошибок) конечно же весьма огорчает
L>>Мое личное мнение — эксепшены хороши в клиентском коде. В серверном коде (и особенно в COM-серверах) им не место. B>А вот в CORBA зачем-то предусмотрены механизмы выброса исключений из серверов и последующей их обработки на клиентах...
А в COM предусмотрен интерфейс IErrorInfo, через который и рекомедуется передавать информацию об ошибках семантического характера. А код возврата HRESULT использовать только для сообщения о наличии ошибки. Передавать через HRESULT свой код нехорошо, поскольку HRESULT используется еще и для сообщения об ошибках системного плана, которые могут возникать при работе системного слоя поддержки COM.
А эксепшены в COMе плохое решение именно потому, что в нем нет такого механизма их передачи через границу процесса
Нет такой идеи, которую нельзя было бы испоганить. Исключения, коды возврата — один хрен в этом смысле.
Хороший пример из COM — с параметрами [out, retval]. Что происходит при генерации wrapper'а? На сях — каждый метод и свойство дублируются — методы — raw, свойства — Get/Set. Хочешь обрабатывать коды возврата — флаг тебе в руки, хочешь ловить исключения — тоже вперед и с песней. Вот это продуманная вещь.
А есть такие системы, не будем тыкать пальцами, где что ни идея, то глюк в реализации.
Хочу спросить — а какие есть мнения по аналогичному вопросу: IErrorInfo сотоварищи vs. GetLastErrorInfo? (Тексты и коды передаются вместе).
Не спора ради, а уточнения для. AVK>А это моя переделка, ибо то что он предлагает оценивать на глаз, та еще с таким малым количеством итераций это поленйший маразм.
Пример действительно не демонстрирует никакого overhead-а.
IMHO, проблема возникает при раскрутке стека вызовов с поиском ближайшего обработчика исключений.
Может оно сейчас эффективней реализуется, прогресс ушел дальше...
Вроде бы даже название говорит о том, что этой техникой предполагалось пользоваться в редких (исключительных) случаях.
AVK>Результат выполения на средненькой по нынешним временам машинке (Celeron 1000) дает такой результат
Не такая она и средненькая.
Успехов!
К этому моменту у меня внутри 0.5, 0.7, 0.33 (с) НС
Здравствуйте WPooh, Вы писали:
WP>IMHO, проблема возникает при раскрутке стека вызовов с поиском ближайшего обработчика исключений. WP>Может оно сейчас эффективней реализуется, прогресс ушел дальше...
Ну дядька то в той статье говорил что главный оверхед именно на создание ексепшена идет. А что касаемо раскрутки стека — если приложение грамотно спроектировано то в тех ситуациях когда исключение генериться часто стек до первого кетча будет совсем коротенький.
AVK>>Результат выполения на средненькой по нынешним временам машинке (Celeron 1000) дает такой результат WP>Не такая она и средненькая.
Но студия на ней работает на пределе. По крайней мере разница между ним и AXP 2000+ разительная. Правда на атлоне памяти не 256 а 512 и память DDR333.
Здравствуйте AndrewVK, Вы писали:
AVK>Ну дядька то в той статье говорил что главный оверхед именно на создание ексепшена идет. А что касаемо раскрутки стека — если приложение грамотно спроектировано то в тех ситуациях когда исключение генериться часто стек до первого кетча будет совсем коротенький.
Про короткий стек — тут писали, что удобно ловить исключение в одном месте, не каждый раз проверять результат выполнения функции и передавать его наверх. Так вот, ИМХО в этом случае и возникает не очень-то короткий стэк до ловушки.
Ну да ладно, тут .NET поднимается, у него вроде бы даже рекомендуется джавовский подход к исключениям. Видимо, механизм переработали.
AVK>>>Результат выполения на средненькой по нынешним временам машинке (Celeron 1000) дает такой результат WP>>Не такая она и средненькая.
AVK>Но студия на ней работает на пределе. По крайней мере разница между ним и AXP 2000+ разительная. Правда на атлоне памяти не 256 а 512 и память DDR333.
Это-твоя машинка. Разработчика. А есть машинки у клиентов. У них может вообще стоять старый пень 100 мегагерцовый с 64 SIMM.
[off]у нас и некоторых разработчиков не уважают — года по три машины не меняют, гады.[/off]
К этому моменту у меня внутри 0.5, 0.7, 0.33 (с) НС
Здравствуйте WPooh, Вы писали:
WP>Здравствуйте AndrewVK, Вы писали:
WP>Не спора ради, а уточнения для. AVK>>А это моя переделка, ибо то что он предлагает оценивать на глаз, та еще с таким малым количеством итераций это поленйший маразм. WP>Пример действительно не демонстрирует никакого overhead-а. WP>IMHO, проблема возникает при раскрутке стека вызовов с поиском ближайшего обработчика исключений. WP>Может оно сейчас эффективней реализуется, прогресс ушел дальше...
WP>Вроде бы даже название говорит о том, что этой техникой предполагалось пользоваться в редких (исключительных) случаях.
Эффективней некуда. В том то вся и прелесть текущей реализации, что оверхэд возникает _только_ при выбрасывании исключения. Потому и советуют их выбрасывать в действительно исключительных ситуациях. Раньше не знаю как у всех, но по крайней мере в нашем компиляторе реализовывалась схема setjmp/longjmp — что дает просто существенный оверхед при _нормальной работе_. Плюс еще и создаются специальные таблицы в сегменте данных, с помошью которых находят обработчики исключений. Собственно поэтому во встроенных системах и реал-тайме, где размер и время работы даже в исключительных ситуациях на вес золота, исключений стараются избегать.
Здравствуйте adb, Вы писали:
adb>Эффективней некуда. В том то вся и прелесть текущей реализации, что оверхэд возникает _только_ при выбрасывании исключения. Потому и советуют их выбрасывать в действительно исключительных ситуациях. Раньше не знаю как у всех, но по крайней мере в нашем компиляторе реализовывалась схема setjmp/longjmp — что дает просто существенный оверхед при _нормальной работе_. Плюс еще и создаются специальные таблицы в сегменте данных, с помошью которых находят обработчики исключений. Собственно поэтому во встроенных системах и реал-тайме, где размер и время работы даже в исключительных ситуациях на вес золота, исключений стараются избегать.
Вот про ваш компилятор — кто это такой, расскажите плиз. Ну или намекните.
Вот у меня вопрос как к специалисту. По стандарту говорится, что деструкторы должны отработать для всех корректно созданных объектов с момента вхождения в try соответствующей ловушки. Как вы осуществляли вызовы деструкторов? Я что-то посмотрел в стандарт, не нашел слов по поводу того, что указатель на деструктор находится первым в таблице методов класса. Да, ежели он виртуальный — он должен быть в vtbl. На этот счет есть флажок или всегда генерируете vtbl и помещаете туда указатель на деструктор в любом случае, вне зависимости от того, виртуальный он или нет? Ну это мелочь, собственно.
А вот более интересно, как определяете какие именно объекты были сконструированы — раскруткой стека и анализом кода? Просто если при нормальной работе overhead-а нет, значит, никакие списки сконструированных объектов не генерируются. Тогда получается, что самая тяжелая операция — анализ на предмет сгенерированных объектов и вызов деструкторов. Это так?
Заранее благодарен за ответ.
К этому моменту у меня внутри 0.5, 0.7, 0.33 (с) НС
Здравствуйте WPooh, Вы писали:
WP>Вот про ваш компилятор — кто это такой, расскажите плиз. Ну или намекните. WP>Вот у меня вопрос как к специалисту. По стандарту говорится, что деструкторы должны отработать для всех корректно созданных объектов с момента вхождения в try соответствующей ловушки. Как вы осуществляли вызовы деструкторов? Я что-то посмотрел в стандарт, не нашел слов по поводу того, что указатель на деструктор находится первым в таблице методов класса. Да, ежели он виртуальный — он должен быть в vtbl. На этот счет есть флажок или всегда генерируете vtbl и помещаете туда указатель на деструктор в любом случае, вне зависимости от того, виртуальный он или нет? Ну это мелочь, собственно. WP>А вот более интересно, как определяете какие именно объекты были сконструированы — раскруткой стека и анализом кода? Просто если при нормальной работе overhead-а нет, значит, никакие списки сконструированных объектов не генерируются. Тогда получается, что самая тяжелая операция — анализ на предмет сгенерированных объектов и вызов деструкторов. Это так?
Деструкторы вызываются для локальных переменных. Их настоящий тип
известен на момент компиляции и проблем с виртуальностью едесь нет никаких.
Если же ты создал объект по new сам его и грохни. Не хочешь возиться с исключениями auto_ptr тебе в помощь.
Любая проблема дизайна может быть решена введением дополнительного абстрактного слоя, за исключением проблемы слишком большого количества дополнительных абстрактных слоев
Здравствуйте Anatolix, Вы писали:
A>Деструкторы вызываются для локальных переменных. Их настоящий тип A>известен на момент компиляции и проблем с виртуальностью едесь нет никаких.
A>Если же ты создал объект по new сам его и грохни. Не хочешь возиться с исключениями auto_ptr тебе в помощь.
Ага, это я знаю. Речь совсем не об этом.
Меня интересует не методика написания программ для корректной обработки исключений и освобождения ресурсов, занятых программой, а как компилятор реализует стандарт. Ну, пусть гипотетический компилятор, не в конкретной инкарнации.
Допустим да, есть у нас таблица всех обработчиков исключений, реализованных в программе — сигнатура исключения и список точек входа в соответствующие ловушки.
А вот мне не понятно то, каким образом происходит поиск объектов, сконструированных с момента входа в блок try той ловушки (соответствующей кинутому исключению), которую мы нашли ближайшей для нашего исключения (хотя это тоже нетривиальный момент, без раскрутки стека не обойдется, просто анализ упростится при помощи этой таблицы). Эту вещь я примерно представляю.
Но вот поиск всех сгенеренных объектов между этими двумя точками — тоже собственно, раскрутка стека и анализ кода процедур (ага, вот тут положили на стек пару int-ов и HANDLER — смещаем стек назад. А вот тут у нас заведен класс типа MyClass — нужно позвать деструктор). Деструкторы объектов на стеке компилятор вызывает при нормальном выходе из блока При бросании исключения, видимо, проще тоже позвать их же, но нужно анализировать branch-и разных ветвлений и пр. ерунду. Просто так передать управление на какую-то точку нельзя, нам же просто нужно деструкторы вызвать, а не продолжить работу — после этого блока может идти дальнейшая обработка данных. С другой стороны, код-то уже есть, нужно просто понять где деструкторы заканчиваются и где начинаются деструкторы другого блока, более объемлющего для данной ветки программы.
То ли помещать проверку после каждого окончания блока — а кинули ли исключение? Да — идем на следующий кусок с деструкторами : нет — продолжаем работу.
Например,
long MyMainFunc()
{
MyClass1 mObj;
try
{
MyClass2 mObj2;
long lVal = 1;
char pBuff[1024];
MyFunc1(1); // can throw exception
}
catch(...)
{
}
}
long MyFunc1(long param)
{
MyClass100 mObj100(param);
if (param>2000)
return -1;
if ((param&0x1)==0x1)
{// pp_1
MyClass3 mObj3(param);
long ind=0;
char pBuff[4];
if (MyFunc2(param++)==3)// point1
mObj3.SomeFunc(param);
else
mObj3.SomeFunc(param+2);
} // p_1
else
{
MyClass4 mObj4(param);
MyFunc2(++param);// point2
mObj4.OtherFunc(param);
} //p_2
MyClass5 mObj5(param);
mObj5.OtherCoolFunction;
}// p_3
long MyFunc2(long param) throw myException
{
if (param>1500)
throw new myException(param);
param += 5;
MyFunc1(param);//point3
}// p_4
Я для нагладности привел взаимную рекурсию из двух функций.
В конце концов кинется исключение. То есть, вызовется специальная функция рантайма.
Допустим, есть таблица с указателями на обработчики — там нашли вхождение myException.
В точках point1, point2 и point3 будем находиться во время выхода из функций при раскрутке стека назад.
В точках p_1, p_2, p_3 и p_4 расположен код вызова нужных нам деструкторов. Вот собственно, проблема — то ли раскручивать код назад (допустим, находимся в point1 — назад до точки pp_1 докрутим, а дальше? Анализировать условия ветвления?), то ли прыгать на деструкторы (эти точки p_X еще надо найти).
Видимо, все-таки строится список сконструированных объектов.
Это мое видение, оно может сильно отличаться от истины. Вот я и хотел спросить знатока, как оно внутри устроено. Там же еще наверняка тонкостей выше крыши. Со списками жизнь проще при выкидывании исключения, но есть overhead при нормальной работе.
Это чисто теоретический интерес, не имеющий никакого прикладного значения.
А как работать с файловыми HANDLE, чтобы при генерации исключения файлики закрывались, GDI и прочие ресурсы освобождать — я не это имел в виду. Спасибо, но немножко не оно.
Если запутанно — извините. Можно поконкретнее пообсуждать. Только вот подозреваю, вопрос не будет обсуждаться. Ибо зачем?
Успехов!
К этому моменту у меня внутри 0.5, 0.7, 0.33 (с) НС
Здравствуйте WPooh, Вы писали:
WP>Если запутанно — извините. Можно поконкретнее пообсуждать. Только вот подозреваю, вопрос не будет обсуждаться. Ибо зачем?
Действительно. если никогда не наблюдал то возьми дизассемблер да посмотри.
Любая проблема дизайна может быть решена введением дополнительного абстрактного слоя, за исключением проблемы слишком большого количества дополнительных абстрактных слоев
Здравствуйте Anatolix, Вы писали:
A>Действительно. если никогда не наблюдал то возьми дизассемблер да посмотри.
Спасибо за совет. Посмотрю на досуге.
Ежели появится adb буду рад с ним поболтать.
Кстати, adb, ты не из XDS случаем?
К этому моменту у меня внутри 0.5, 0.7, 0.33 (с) НС
Re[11]: Исключения или коды возврата?
От:
Аноним
Дата:
01.10.02 13:39
Оценка:
Здравствуйте WPooh, Вы писали:
WP>Здравствуйте Anatolix, Вы писали:
A>>Действительно. если никогда не наблюдал то возьми дизассемблер да посмотри. WP>Спасибо за совет. Посмотрю на досуге.
WP>Ежели появится adb буду рад с ним поболтать. WP>Кстати, adb, ты не из XDS случаем?
Уже нет -)). Два года назад ушел оттуда.
Собственно я далеко не специалист в этой области. Во-вторых они пишут Java native compiler. А в натуральной Java такой проблемы в принципе нету. Там все объекты создаются в куче и рулятся gc'ом. В XDS компиляторе научились таки в некоторых случаях размешать объекты на стеке, поэтомуй как-то они эту проблему решили. В принципе попробую посмотреть или тупо спросить.
А вообще могу статейку кинуть, которая так и называется "Zero-Overhead Exception Handling Using Metaprogramming", либо в инете её поищи.
Здравствуйте, WPooh, Вы писали:
WP>Это-твоя машинка. Разработчика. А есть машинки у клиентов. У них может вообще стоять старый пень 100 мегагерцовый с 64 SIMM. WP>[off]у нас и некоторых разработчиков не уважают — года по три машины не меняют, гады.[/off]
Даже если три года не менять машину — такого старья быть не может...
На такой машине Win 2000 работает очень с трудом....
Здравствуйте, Max.Subpixel, Вы писали:
MS>Даже если три года не менять машину — такого старья быть не может... MS>На такой машине Win 2000 работает очень с трудом....
А если посмотреть на год сообщения, то получим 2002-3=1999.
В общем, было такое старье. Trust me.
К этому моменту у меня внутри 0.5, 0.7, 0.33 (с) НС
Здравствуйте, WPooh, Вы писали:
WP>Здравствуйте, Max.Subpixel, Вы писали:
MS>>Даже если три года не менять машину — такого старья быть не может... MS>>На такой машине Win 2000 работает очень с трудом.... WP>А если посмотреть на год сообщения, то получим 2002-3=1999. WP>В общем, было такое старье. Trust me.
не заметил
ну правда я помню, что в 99 мы закупали в офис 433 целерон с 14Гб винтами и 17 дюймами мониторов...