Ключевое слово checked

Ключевое слово checked

Вы, несомненно, прекрасно знаете, что любой числовой тип данных имеет свои строго заданные верхний и нижний пределы (значения которых можно выяснить программными средствами с помощью свойств MaxValue и MinValue). При выполнении арифметических операций с конкретным типом вполне возможно случайное переполнение блока хранения данного типа (попытка присвоения типу значения, которое оказывается больше максимально допустимого) или потеря значимости (попытка присвоения значения, которое оказывается меньше минимально допустимого). Чтобы "идти в ногу" с CLR, обе эти возможности будут обозначаться, как "переполнение". (И переполнение, и потеря значимости приводят к созданию типа System.OverflowException. Типа System.UnderflowException в библиотеках базовых классов нет.)

Для примера предположим, что мы создали два экземпляра типа System.Byte (тип byte в C#), присвоив им значения, не превышающие максимального (255). При сложении значений этих типов (с условием преобразования результата в тип byte) хотелось бы предполагать, что результат будет точной суммой соответствующих членов.

namespace CheckedUnchecked {

 class Program {

  static void Main(string[] args) {

   // Переполнение для System.Byte.

   Console.WriteLine("Макс, значение для byte равно {0}", byte.MaxValue);

   Console.WriteLine("Мин. значение для byte равно {0}", byte.MinValue);

   byte b1 = 100;

   byte b2 = 250;

   byte sum = (byte)(b1 + b2);

   // Значением sum должно быть 350, но.…

   Console.WriteLine("sum = {0}", sum);

   Console.ReadLine();

  }

 }

}

Вывод этого приложения покажет, что sum содержит значение 94 (а не ожидаемое 350). Причина очень проста. Поскольку System.Byte может содержать только значения, находящиеся между 0 и 255 (что в итоге составляет 256 значений), sum будет содержать значение переполнения (350 – 256 = 94). Как видите, в отсутствие специальной коррекции переполнение происходит без генерирования исключений. Иногда скрытое переполнение не создает никаких проблем. В других случаях соответствующая потеря данных может быть совершенно неприемлемой.

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

// Использование int для sum, чтобы не допустить переполнения.

byte b1 = 100;

byte b2 = 250;

int sum = b1 + b2;

Конечно, проблемой этого подхода является то, что вы – человек, а значит, при всех ваших усилиях, могут остаться ошибки, ускользнувшие от вашего взгляда. Поэтому в C# предлагается ключевое слово checked. При помещении оператора (или блока операторов) в рамки контекста ключевого слова checked компилятор C# генерирует специальные CIL-инструкщии, с помощью которых проверяются условия переполнения, возможные при выполнении сложения, умножение, вычитания или деления числовых типов данных. Если происходит переполнение, среда выполнения генерирует тип System.OverflowException. Рассмотрите следующую модификацию программы.

class Program {

 static void Main(string[] args) {

  // Переполнение для System.Byte.

  Console.WriteLine("Макс. значение для byte равно {0}.", byte.MaxValue);

  byte b1 = 100;

  byte b2 = 250;

  try {

   byte sum = checked((byte)(b1 + b2));

   Console.WriteLine("sum = {0}", sum);

  } catch (OverflowException e) { Console.WriteLine(e.Message); }

 }

}

Здесь оператор сложения b1 и b2 помещается в контекст ключевого слова checked. Если вы хотите, чтобы проверка переполнения происходила для блока программного кода, можно взаимодействовать с ключевым словом checked так, как показано ниже.

try {

 checked {

  byte sum = (byte)(b1 + b2);

  Console.WritaLine(sum = {0}", sum);

 }

} catch (OverflowException e) {

 Console.WriteLine(e.Message);

}

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

Проверки переполнения для всего проекта

Если вы создаете приложение, которое не должно позволять скрытое переполнение ни при каких условиях, будет слишком утомительно указывать ключевое слово checked для каждой строки программного кода. В качестве альтернативы компилятор C# предлагает использовать флаг /checked. Когда этот флаг активизирован, все арифметические операции будут проверяться на переполнение без указания ключевого слова checked. Если обнаружится переполнение, вы получите OverflowException среды выполнения.

Чтобы активизировать этот флаг в Visual Studio 2005, откройте страницу свойств проекта и щелкните на кнопке Advanced на вкладке Build. В появившемся диалоговом окне отметьте флажок Check for arithmetic overflow/underflow (Проверять условия переполнения/потери значимости для арифметических операций), рис. 9.3.

Рис. 9.З. Активизация проверки переполнения в Visual Studio 2005

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

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Слово об оптимизации

Из книги Давайте создадим компилятор! автора Креншоу Джек

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


Ключевое слово static

Из книги Язык программирования С# 2005 и платформа .NET 2.0. [3-е издание] автора Троелсен Эндрю

Ключевое слово static Как уже говорилось в этой главе, члены классов (и структур) в C# могут определяться с ключевым cловом static В этом случае соответствующий член должен вызываться непосредственно на уровне класса, а не экземпляра типа. Для иллюстрации рассмотрим "знакомый"


Хранение семейных тайн: ключевое слово protected

Из книги Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT автора Фролов Александр Вячеславович

Хранение семейных тайн: ключевое слово protected Вы уже знаете, что открытые элементы непосредственно доступны отовсюду, а приватные элементы недоступны для объектов вне класса, определяющего эти элементы. Язык C#, занимающий лидирующие позиции среда многих других


Получение интерфейсных ссылок: ключевое слово as

Из книги Феномен науки. Кибернетический подход к эволюции автора Турчин Валентин Фёдорович

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


Получение интерфейсных ссылок: ключевое слово is

Из книги Scrum и XP: заметки с передовой автора Книберг Хенрик

Получение интерфейсных ссылок: ключевое слово is Можно также проверить реализацию интерфейса с помощью ключевого слова is. Если соответствующий объект не совместим указанным интерфейсом, будет возвращено значение false. А если тип совместим с интерфейсом, вы можете смело


Ключевое слово unchecked

Из книги Тайм-менеджмент для системных администраторов автора Лимончелли Томас

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


Ключевое слово sizeof

Из книги VBA для чайников автора Каммингс Стив

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


Ключевое слово this

Из книги Искусство программирования на языке сценариев командной оболочки автора Купер Мендель

Ключевое слово this Ключевое слово this представляет собой указатель на текущий объект класса. Методы класса могут использовать ключевое слово this чтобы получить указатель на объект для которого вызван данный метод. Указатель this представляет собой постоянную величину, вы не


Заключительное слово

Из книги Linux и все, все, все... Статьи и колонки в LinuxFormat, 2006-2013 автора Федорчук Алексей Викторович

Заключительное слово Фух! Вот уж не ожидал, что это займёт столько времени.Надеюсь, эта книга навеяла вам несколько полезных идей, будь вы новичками или уже бывалыми специалистами.Поскольку Scrum всё равно необходимо подстраивать под каждую конкретную среду, спор по поводу


Вступительное слово

Из книги автора

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


Ключевое средство отладки: окно Watches

Из книги автора

Ключевое средство отладки: окно Watches Когда вы освоите работу с окном Locals, работа с окном Watches (Окно контролируемых выражений) покажется просто забавой. Окно Watches делает, по сути, то же самое, что и окно Locals, но с одним очевидным отличием - те выражения, значения которых будут


КЛЮЧЕВОЕ СЛОВО return

Из книги автора

КЛЮЧЕВОЕ СЛОВО return      Принципы программирования на языке Си основаны на понятии функции. В представленных ранее примерах программирования мы уже воспользовались несколькими функциями: printf( ), scanf( ), getchar( ), putchar( ) и strlen( ). Эти функции являются системными, однако мы