Какие файлы заголовков не должны быть защищены от множественного включения?

Я прочитал исходный код dcmtk и нашел комментарий в ofstdinc.h:

// this file is not and should not be protected against multiple inclusion

А какие типы файлов заголовков СЛЕДУЕТ быть защищены от множественного включения?

Ответы

Ответ 1

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

// define INCLUDE_STACK to include "ofstack.h"
#ifdef INCLUDE_STACK
#include "dcmtk/ofstd/ofstack.h"
#endif

Итак, если бы я хотел включить "ofstack.h", я бы сделал так:

#define INCLUDE_STACK
#include "ofstdinc.h"
#undef INCLUDE_STACK

Теперь, представьте позже в строке, кто-то хочет использовать этот конкретный раздел заголовка:

// define INCLUDE_STRING to include "ofstring.h"
#ifdef INCLUDE_STRING
#include "dcmtk/ofstd/ofstring.h"
#endif

Итак, они делают следующее:

#define INCLUDE_STRING
#include "ofstdinc.h"
#undef INCLUDE_STRING

Если "ofstdinc.h" включил охранники, он не будет включен.

Ответ 2

Одним из примеров являются файлы заголовков, которые ожидают, что вы определите макрос. Рассмотрим заголовок m.h с

M( foo, "foo" )
M( bar, "bar" )
M( baz, "baz" )

Это можно использовать в каком-то другом заголовке:

#ifndef OTHER_H
#define OTHER_H

namespace other
{
    enum class my_enum
    {
#define M( k, v ) k,
#include "m.h"
#undef M
    };

    void register_my_enum();
}

#endif

и в другом файле (возможно, в реализации):

#include "other.h"

namespace other
{
    template< typename E >
    void register_enum_string( E e, const char* s ) { ... }

    void register_my_enum()
    {
#define M( k, v ) register_enum_string( k, v );
#include "m.h"
#undef M
    }
}

Ответ 3

Вы почти всегда хотите защитить от множественного включения. Единственный раз, когда вы не хотите этого делать, - это если вы делаете какие-то причудливые вещи с макросами C, и поэтому ХОТИТЕ иметь множественное включение, чтобы получить генерируемое кодовое слово (не используйте пример этого небрежно).