В C и C++, почему каждый.h файл обычно окружается #ifndef #define #endif директивы?

То, почему делает каждый.h файл, запускается с #ifndef #define #endif? Мы можем, конечно, скомпилировать программу без тех директив.

7
задан Brian Tompsett - 汤莱恩 20 February 2016 в 22:19
поделиться

5 ответов

Это так называемый "include guard". Целью является предотвращение необходимости многократного разбора файла, если он включен многократно.

14
ответ дан 6 December 2019 в 08:43
поделиться

Поскольку числа с плавающей запятой неточны (Википедия)

-121--3426521-

Она называется защитой включения. Вы можете писать без них, пока не начнете писать большие программы и не узнаете, что нужно включить один и тот же файл .h несколько раз, прямо или косвенно, из файла .c. Тогда без защиты включения вы получите несколько ошибок определения, но с ними содержимое файла заголовка анализируется только один раз и пропускается все последующее время, избегая этих ошибок. Это хорошая практика всегда использовать их.

-121--3815270-

Предотвращает включение нескольких файлов. То же самое можно сделать с помощью директивы

#pragma once

, но эти # ifndefs являются стандартными, поэтому поддерживаются каждым компилятором.

4
ответ дан 6 December 2019 в 08:43
поделиться

pcntl _ fork , вероятно, работает так, как вы думаете: он разворачивает текущий процесс, так же, как и С-функция:

Функция pcntl _ fork () создает дочерний процесс, который отличается от родительский процесс только в его PID и PPID.
Пожалуйста, смотрите вашу систему вилка (2) справочная страница для конкретных подробные сведения о том, как вилка работает на вашем система.


Но, цитируя Введение в раздел «Управление процессом» руководства:

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

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


И, прежде чем начать использовать эту функцию, не забывайте, что:

Примечание: Это расширение недоступно на платформах Windows.

-121--2672395-

Поскольку числа с плавающей запятой неточны (Википедия)

-121--3426521-

Она называется защитой включения. Вы можете писать без них, пока не начнете писать большие программы и не узнаете, что нужно включить один и тот же файл .h несколько раз, прямо или косвенно, из файла .c. Тогда без защиты включения вы получите несколько ошибок определения, но с ними содержимое файла заголовка анализируется только один раз и пропускается все последующее время, избегая этих ошибок. Это хорошая практика всегда использовать их.

3
ответ дан 6 December 2019 в 08:43
поделиться

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

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

#ifndef SZ
#define SZ 1024
#else
#if SZ == 1024
#undef SZ
#define SZ 128
#else
#error "You can include me no more than two times!"
#endif
#endif

Теперь, если вы включите заголовочный файл один раз, вы получите SZ равный 1024. Если вы включите его дважды, то SZ станет 128. Конечно, большинство реальных программистов не вредоносны, и никто на самом деле не пишет подобный код.

Обратите внимание, что стандарт языка Си позволяет assert.h быть #included несколько раз с различным поведением в зависимости от того, определено ли NDEBUG на момент включения assert.h. Таким образом, assert.h не может включать охранников. Это особенность, а не ошибка.

1
ответ дан 6 December 2019 в 08:43
поделиться

Если файл заголовка содержит определение, такое как

int i;
, чем, включенные несколько раз без охранника, приведет к ошибке компиляции.
IFNDEF Проверяет, что некоторая препроцессорная переменная не определена (и в первую очередь нет), то определяет его явно, чтобы избежать захвата снова. В MSVC вы также можете использовать
#pragma once
вместо ifndef.
-1
ответ дан 6 December 2019 в 08:43
поделиться