Препроцессор #ifndef - PullRequest
       26

Препроцессор #ifndef

0 голосов
/ 13 марта 2012

Предположим, у меня есть a.h, что включает в себя следующее:

<stdbool.h>
<stddef.h>
<stdin.h>

Предположим, у меня также есть b.h, которое также включает <stdbool.h>.Если a.h содержит оператор определения препроцессора #ifndef, а b.h - нет.a.h будет включать только то, что не было включено в b.h?Таким образом, когда b.h включает a.h, будет a.h включать stddef.h и stein.h и не включать заново stdbool.h, или эти функции определения препроцессора используются только для того, чтобы увидеть, переопределен ли весь этот класс, и не являются ли они конкретнымифункции внутри него?

РЕДАКТИРОВАТЬ:

Кроме того, предположим, что b.h включает в себя еще один заголовочный файл, который включает stdbool.h - что делает b.h иметь stdbool.h как из этого класса, так и a.h.Это приведет к ошибкам?

Ответы [ 3 ]

1 голос
/ 13 марта 2012

Все стандартные заголовки C должны быть сделаны так, чтобы их можно было включить несколько раз и в любом порядке:

Стандартные заголовки могут быть включены в любом порядке; каждый может быть включен более одного раза в данной области, без эффекта, отличного от включается только один раз

1 голос
/ 13 марта 2012

Если stdbool.h сам имеет охранников (#ifndef), то все будет хорошо. В противном случае вы можете включить заголовки дважды. Это вызовет проблемы? Это зависит. Если дважды включенный заголовок содержит только объявления, то все скомпилируется - это займет всего несколько наносекунд дольше. Представь себе:

int the_answer(void); // <-- from first inclusion
int the_answer(void); // <-- from from second inclusion - this is OK
                      //       at least as long as declarations are the same

int main()
{
    return the_answer();
}

Если, с другой стороны, будут определения, это вызовет ошибку:

int the_answer(void)  // <-- from first inclusion - OK so far
{
    return 42;
}

int the_answer(void)  // <-- from second inclusion
{                     //     error: redefinition of 'the_answer'
    return 42;
}

int main()
{
    return the_answer();
}
0 голосов
/ 13 марта 2012

Обычно заголовок начинается с

#ifndef _HEADERFILENAME_H_
#define _HEADERFILENAME_H_

и заканчивается следующей строкой:

#endif

Если вы включите заголовок два раза, во второй раз ваша программа не будет снова включать полный заголовок из-за #ifndef, #define и #endif

...