Читаем Linux программирование в примерах полностью

«В конце концов, абсурдно делать тщательные проверки безопасности при отладочных запусках, когда к результатам нет никакого доверия, а затем удалять их из финальных версий, когда ошибочный результат может быть дорогим или катастрофическим. Что бы мы подумали об энтузиасте-мореплавателе, который надевает свой спасательный жилет при тренировке на сухой земле и снимает его, как только выходит в море?»

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

Наконец, отметим следующее из раздела «Ошибки» справочной страницы GNU/Linux assert(3):

assert() реализован как макрос: если у проверяемого выражения есть побочные результаты, поведение программы может меняться в зависимости от того, определен ли NDEBUG. Это может создавать гейзенберговские ошибки, которые исчезают при отключении режима отладки.

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

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

Справочная страница предостерегает нас от использования при вызовах assert() выражений с побочными эффектами:

assert(*p++ == '\n');

Здесь побочным эффектом является увеличение указателя p как часть теста. Когда определен NDEBUG, аргумент выражения исчезает из исходного кода; он никогда не исполняется. Это может привести к неожиданной неудаче. Однако, как только при подготовке к отладке запрет на операторы проверки отменяется, все начинает снова работать! Такие проблемы трудно отследить.

<p>12.2. Низкоуровневая память: функции <code>mem<emphasis>XXX</emphasis>()</code></p>

Несколько функций предоставляют возможность для работы с произвольными блоками памяти низкоуровневые службы. Все их имена начинаются с префикса 'mem':

#include /* ISO C */

void *memset(void *buf, int val, size_t count);

void *memcpy(void *dest, const void *src, size_t count);

void *memmove(void *dest, const void *src, size_t count);

void *memccpy(void *dest, const void *src, int val, size_t count);

int memcmp(const void *buf1, const void *buf2, size_t count);

void *memchr(const void *buf, int val, size_t count);

<p>12.2.1. Заполнение памяти: <code>memset()</code></p>

Функция memset() копирует значение val (интерпретируемое как unsigned char) в первые count байтов буфера buf. Она особенно полезна для обнуления блоков динамической памяти:

void *p = malloc(count);

if (p != NULL)

 memset(p, 0, count);

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

<p>12.2.2. Копирование памяти: <code>memcpy()</code>, <code>memmove()</code> и <code>memccpy()</code></p>

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

void *memcpy(void *dest, const void *src, size_t count)

Это простейшая функция. Она копирует count байтов из src в dest. Она не обрабатывает перекрывающиеся области памяти. Функция возвращает dest.

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

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

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

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