Читаем Язык программирования C++. Пятое издание полностью

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

Упражнения раздела 6.5.2

Упражнение 6.43. Какое из следующих объявлений и определений имеет смысл поместить в файл заголовка, а какой — в текст файла исходного кода? Объясните почему.

(a) inline bool eq(const BigInt&, const BigInt&) {...}

(b) void putValues(int *arr, int size);

Упражнение 6.44. Перепишите функцию isShorter() из раздела 6.2.2 как встраиваемую.

Упражнение 6.45. Пересмотрите функции, написанные для предыдущих упражнений, и решите, должны ли они быть определены как встраиваемые. Если да, то сделайте это. В противном случае объясните, почему они не должны быть встраиваемыми.

Упражнение 6.46. Возможно ли определить функцию isShorter как constexpr? Если да, то сделайте это. В противном случае объясните, почему нет.

<p>6.5.3. Помощь в отладке</p>

Для условного выполнения отладочного кода программисты С++ иногда используют подход, подобный защите заголовка (см. раздел 2.6.3). Идея в том, что программа будет содержать отладочный код, который выполняется только во время разработки программы. Когда приложение закончено и готово к выпуску, отладочный код исключается. Этот подход подразумевает использование двух средств препроцессора: assert и NDEBUG.

Макрос препроцессора assert

Макросassert — это макрос препроцессора (preprocessor macro). Макрос препроцессора — это переменная препроцессора, действующая как встраиваемая функция. Макрос assert получает одно выражение и использует его как условие:

assert(выражение);

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

Действие макроса препроцессора подобно вызову функции. Макрос assert получает одно выражение, которое он использует как условие.

Макрос assert определен в заголовке cassert. Как уже упоминалось, относящиеся к препроцессору имена обрабатывает препроцессор, а не компилятор (см. раздел 2.3.2). В результате такие имена можно использовать непосредственно, без объявления using. Таким образом, используется имя assert, а не std::assert, кроме того, для него не предоставляется объявление using.

Макрос assert зачастую используется для проверки "недопустимых" условий. Например, программа обработки вводимого текста могла бы проверять, что все вводимые слова длиннее некоего порогового значения. Эта программа могла бы содержать такой оператор:

assert(word.size() > threshold);

Переменная препроцессора NDEBUG

Поведение макроса assert зависит от состояния переменной препроцессора NDEBUG. Если переменная NDEBUG определена, макрос assert ничего не делает. По умолчанию переменная NDEBUG не определена, поэтому по умолчанию макрос assert выполняет проверку.

Отладку можно "выключить", предоставив директиву #define, определяющую переменную NDEBUG. В качестве альтернативы большинство компиляторов предоставляет параметр командной строки, позволяющий определять переменные препроцессора:

$ CC -D NDEBUG main.С # use /D with the Microsoft compiler

Результат будет тот же, что и при наличии строки #define NDEBUG в начале файла main.С.

Когда переменная NDEBUG определена, программа во время выполнения избегает дополнительных затрат на проверку различных условий. Самих проверок во время выполнения, конечно, тоже не будет. Поэтому макрос assert следует использовать только для проверки того, что действительно недопустимо. Это может быть полезно при отладке программы, но не должно использоваться для замены логических проверок времени выполнения или проверки ошибок, которые должна осуществлять программа.

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

void print(const int ia[], size_t size) {

#ifndef NDEBUG

// __func__ - локальная статическая переменная, определенная

// компилятором. Она содержит имя функции

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных