Правила программирования на Си и Си++



         

159. Назначение исключений — не быть пойманными - часть 3


bytes_written = f.Write( data, sizeof(data));

if( bytes_written != sizeof(data) )

   // разобраться с этим

Вторая проблема одновременно более тонкая и более серьезная. Вы не сможете исправить эту ошибку. Во-первых, вы не знаете, сколько байтов было записано перед тем, как диск переполнился. Если Write()

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

Даже когда Write()

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

переписать, как показано ниже, то она все равно не будет работать:

char  data[128];

CFile f( "some_file", CFile::modeWrite );

int bytes_written;

try

{

   bytes_written = f.Write( data, sizeof(data) );

}

catch( CFileException &r )

{

   if( r.m_cause == CFileException::diskFull )

   // что-то выполнить.

   // при этом переменная bytes_written содержит мусор.

}

Управление передается прямо откуда-то изнутри Write() в обработчик catch при возбуждении исключения, перескакивая через все операторы return внутри Write(), а также через оператор присваивания в вызывающейся функции; переменная bytes_written

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

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

Последней проблемой являются непроизводительные затраты. Обработка исключения вызывает очень большие непроизводительные затраты, выражающиеся в возрастании в несколько раз размера кода и времени выполнения. Это происходит даже в операционных системах типа Microsoft Windows NT, которые поддерживают обработку исключений на уровне операционной системы. Вы можете рассчитывать на 10-20% увеличение размера кода и падение скорости выполнения на несколько процентов при интенсивном использовании исключений.14

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

обычно, при наличии возможности, предпочесть возврат ошибки.




Содержание  Назад  Вперед