Глава 4. Препроцессор____________________________________9_1_

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

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

Один из возможных приемов состоит в использовании директивы #error для выявления семантических несоответствий. Хотя это не всегда просто, небольшие усилия могут сохранить вам впоследствии многие часы. Если вы можете идентифицировать смысловые взаимоотношения, то уместное применение tterror вызовет остановку компиляции при их нарушении. Ваше дело — выявить взаимосвязи и определить, что считать нарушением, а директива fterror поможет вам их вскрыть.

Ни один из предложенных приемов не способен стать панацеей; найти каждому адекватное применение — это вопрос вашего мастерства.

assert

Средствами препроцессора было сконструировано макроопределение, известное как assert (assertion в данном случае переводится, видимо, как логическое суждение, утверждение). Подробности вы можете найти в файле \Bc5\Include\assert.h; здесь его код не приводится, поскольку нам достаточно общего представления о функционировании этого макроопределения.

Макроопределение assert (это означает, что оно создано при помощи директивы ftdefine) имеет один аргумент, значение которого можно рассматривать как логическое, то есть это может быть любое арифметическое или условное выражение, принимающее целочисленное значение. Нулевое значение интерпретируется как false, а любое ненулевое — как true. Если условие ложно (false), то assert прерывает выполнение программы, сообщая, что утверждение неверно, с указанием имени файла и номера строки, где это произошло.

Как работает asseft. Функция assert реализована именно как макрос, потому что в его состав входят ключевые слова _FILE_ и _LINE_. Они имеют смысл для любого файла и доступны при отладке. Причина использования макроопределения заключается в производимой им' подстановке текста — ведь имя, определенное через #define, повсюду заменяется своим определением. Эта замена необходима постольку, поскольку в противном случае значения _LINE_ и _FILE_ будут содержать не действительные координаты места, где произошло опровержение утверждения, а всегда одни и те же значения, соответствующие месту, где функция была определена.