Решить, какие стандартные заголовочные файлы включить в #include - PullRequest
2 голосов
/ 10 марта 2011

Предположим, я редактирую какой-то большой исходный файл C ++ и добавляю несколько строк кода, которые используют auto_ptr, как в следующем примере.

#include <string>

// ... (much code here)

void do_stuff()
{
    std::string str("hello world");
    // ... (much code here too)
    std::auto_ptr<int> dummy; // MY NEW CODE
    // ...
}

Этот пример компилируется на gcc 3.4.4 (cygwin), потому что стандартный заголовок <string> содержит заголовок <memory>, необходимый для компиляции auto_ptr. Однако это не работает на gcc 4.5.0 (mingw); похоже, они очистили свои заголовочные файлы или что-то в этом роде.

Итак, когда я добавляю код, который использует auto_ptr, должен ли я немедленно пойти посмотреть, содержит ли файл #include <memory> в начале, как предполагает этот ответ ? Я никогда не делаю это (я нахожу это слишком раздражающим); я всегда полагаюсь на компилятор, чтобы проверить, отсутствует ли какой-либо #include.

Есть ли какая-либо опция, которая не мешала бы кодированию и обеспечивала бы переносимость моего кода?

Существует ли реализация стандартной библиотеки C ++, заголовки которой не включают друг друга больше, чем требуется?

Ответы [ 3 ]

10 голосов
/ 10 марта 2011

Если вы используете что-то в стандартной библиотеке, вы должны включить заголовок, в котором это определено. Это единственный портативный вариант. Таким образом вы избегаете цитируемого вами случая, когда один заголовок включает другой в одну версию или компилятор, но не другой. auto_ptr определено в <memory>, поэтому, если вы используете его, включите этот заголовок.

[править ...]

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

Точное определение способа включения заголовка - тоже непростая задача. Если вы используете стандартное определение библиотеки, то вы должны каким-то образом включить заголовок. Компилятор должен будет указать, включили ли вы заголовок самостоятельно (возможно, через собственные или сторонние заголовки библиотеки) или он пришел через заголовок другой стандартной библиотеки. (Например, в вашем примере он должен быть в состоянии определить разницу между <memory>, включенным через <string> или включенным в ваш собственный код.)

Это должно было бы обрабатывать разные версии стандартной библиотеки (например, C ++ 03 и C ++ 0x) и разных поставщиков. А что, если эти поставщики стороннего stdlib не следуют стандарту, вы можете получить неверные предупреждения о том, какие заголовки включить.

Я только говорю это, чтобы попытаться объяснить (с моим ограниченным знанием компилятора / stdlib), почему я не думаю, что компиляторы имеют эту функцию. Я согласен, это было бы полезно, но я думаю, что цена перевешивает выгоду.

1 голос
/ 10 марта 2011

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

0 голосов
/ 11 марта 2011

Как правило, заголовочные файлы содержат «include guard». Охранники образованы:

MyHeader.h:

#ifndef __MY_HEADER_H__
#    define __MY_HEADER_H__

     //body of MyHeader.h

#endif

Итак, вы можете включать MyHeader.h столько раз, сколько захотите:

#include "MyHeader.h"
#include "MyHeader.h"
#include "MyHeader.h"
#include "MyHeader.h"

И это не вызовет проблем у компилятора (он будет включен только один раз). Кроме того, вы можете включить другой файл, который включает в себя «MyHeader.h», и то же правило будет применяться.

Что это означает, если вы хотите использовать что-то, что определено в заголовке - включите это! (Даже если вы думаете, что что-то еще может включать это, нет причин не быть в безопасности).

...