Разница между использованием #include ‹filename› и #include ‹filename.h› в C ++

В чем разница между использованием #include<filename> and #include<filename.h> в C ++? Что из двух используется и почему?


person yesraaj    schedule 19.11.2008    source источник
comment
Голосование для открытия. Этот вопрос касается <foo> и <foo.h>, тогда как связанный вопрос о <foo(.h)> vs "foo(.h)". Связанный вопрос, безусловно, является связанным и полезным ресурсом, но это не дубликат.   -  person Heinzi    schedule 12.05.2017


Ответы (5)


Включаемые файлы только C ++, не входящие в стандарт C, никогда не использовались filename.h. С момента выхода самого первого стандарта C ++ (1998 г.) они использовали filename для своих собственных заголовков.

Файлы, унаследованные стандартом C, стали cfilename вместо filename.h. Унаследованные файлы C, используемые как filename.h, устарели, но по-прежнему являются частью стандарта C ++.

Разница в том, что имена, не определенные как макросы в C, находятся в пространстве имен std:: в cfilename в C ++, а имена в filename.h находятся в области глобального пространства имен. Таким образом, вы найдете ::size_t в stddef.h и std::size_t в cstddef. Оба являются стандартным C ++, но использование :: size_t не рекомендуется (см. Приложение D к стандарту C ++).

Вот в чем разница.

Зачем вам использовать `filename.h`?

  • Совместимость с компиляторами C
  • Совместимость с очень старыми компиляторами C ++

Почему вам следует использовать cfilename?

  • Имена находятся в пространстве имен std::. Больше никаких именных столкновений.
  • Новые возможности C ++ (например, перегруженные математические функции для чисел с плавающей запятой, long)
  • Заголовки совместимости C (filename.h) могут исчезнуть в будущем.
person Johannes Schaub - litb    schedule 19.11.2008
comment
Спасибо, не могли бы вы объяснить? Разница в том, что имена, не определенные как макросы в C, находятся в пространстве имен std :: in cfilename в C ++ - person yesraaj; 19.11.2008
comment
Что ж. Препроцессор не знает о пространствах имен C ++. Его не волнует никакая сфера действия. Таким образом, C ++ не может помещать макросы в пространства имен. В стандарте прямо говорится, что даже если C допускает реализацию в виде функций, реализации C ++ все равно должны делать их макросами. Это, как следствие, и хорошо. - person Johannes Schaub - litb; 19.11.2008
comment
Даже если они устарели, ни один здравомыслящий поставщик компиляторов никогда не откажется от использования filename.h в C ++. Они сломали бы слишком много программ и рассердили бы слишком много клиентов / разработчиков. - person Tom Barta; 20.11.2008
comment
устаревание не означает, что это не сработает. вы также все равно не заметите, если не будет предупреждения. в конце концов, компиляторы не обязаны их предоставлять. - person Johannes Schaub - litb; 20.11.2008
comment
Устаревание определено как нормативное для текущей редакции стандарта, но не обязательно будет частью стандарта в будущих редакциях. - person Johannes Schaub - litb; 20.11.2008
comment
Ваше объяснение по-прежнему актуально для #include "foo.h" и #include "foo"? Извините, я новичок. - person Friendly Ghost; 04.09.2018

#include <foo.h> был распространен в коде C ++ до стандарта C ++. Стандарт изменил его на #include <foo>, где все из заголовка было помещено в пространство имен std. (Спасибо litb за указание на то, что в стандарте никогда не разрешались заголовки .h.)

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

В большинстве компиляторов старые заголовки все еще существуют для обратной совместимости (и совместимости с C), но современные программы на C ++, которые хотят следовать стандарту, не должны их использовать.

В случае стандартных заголовков C версии C ++ имеют в начале c, поэтому заголовок C

#include <stdio.h>

становится

#include <cstdio>
person CAdaker    schedule 19.11.2008
comment
Как? Как вы просто написали включить в свой ответ? Я совершенно сбит с толку твоей крутизной :) - person Robert Gould; 19.11.2008
comment
Блоки кода, написанные с помощью обратных кавычек, похоже, подходят для lt и gt. знак равно - person CAdaker; 19.11.2008
comment
применимо ли это только к стандартным заголовкам? - person yesraaj; 19.11.2008
comment
да. Я добавлю об этом строчку. - person CAdaker; 19.11.2008
comment
Кроме того, здесь вы делаете ту же ошибку. filename.h (как и iostream.h) никогда не входил ни в один стандарт c +. - person Johannes Schaub - litb; 19.11.2008
comment
О, я не знал об этом. Поменяю на предстандартное чтение. - person CAdaker; 19.11.2008
comment
На самом деле, #include ‹standard hdr› не обязательно искать файл. Это может быть реализовано иначе, например с использованием предварительно скомпилированных заголовков. Это может быть быстрее (подумайте о доставке предварительно скомпилированных заголовков) - person MSalters; 20.11.2008
comment
MSalters прав. это может быть что угодно, включая виртуальный файл в компиляторе :) - person Johannes Schaub - litb; 20.11.2008
comment
Да, ты прав. Но он работает так же, как если бы он искал файл, поэтому я не чувствовал, что это достаточно актуально, чтобы упоминать. - person CAdaker; 21.11.2008

В старом стандарте использовался синтаксис #include <filename.h>. Когда к языку были добавлены пространства имен и шаблоны, стандарт был изменен на #include <filename>.

Это было сделано для того, чтобы все стандартные библиотеки можно было разместить в пространстве имен std. Старый код, в котором не было концепции пространств имен, все равно будет работать, поскольку файлы #include <filename.h> не используют пространства имен.

Новый код должен всегда использовать формат #include <filename>. Если вы используете старый формат, все символы, которые они определяют, будут помещены в глобальное пространство имен, а не в std.

person Ferruccio    schedule 19.11.2008
comment
Не существовало старого стандарта, в котором использовалось бы filename.h. Это было обычным явлением среди компиляторов до того, как появился первый стандарт С ++. - person Johannes Schaub - litb; 19.11.2008
comment
:-) вот что мне нравится abt stackoverflow - person yesraaj; 19.11.2008
comment
хорошо, стандарт, возможно, был немного строгим. Я должен был сказать, что это де-факто стандарт или обычная практика. - person Ferruccio; 19.11.2008

Файлы без .h - это файлы заголовков C ++, а файлы с .h - файлы заголовков C. Это относится только к стандартным файлам заголовков в C ++.

Если вы включаете свои собственные файлы или файлы, которые не являются частью стандартного C ++, вам всегда нужно писать полное имя файла (которое может быть любым).

person Magnus Westin    schedule 19.11.2008

Если вы говорите о стандартных библиотеках (потому что иначе они вообще не работают), разница в том, что

#include< header >
//my code

- это правильный способ вызвать заголовок в соответствии со стандартом C ++, а

#include< header.h >
//my code

устарел (в стандарте C ++, но по-прежнему необходим в соответствии со стандартом C99) и поставляется вместе с остальным багажом C.

Итак, вы должны использовать:

#include< cmath >
//my code

нет:

#include< math.h >
//my code
person Robert Gould    schedule 19.11.2008
comment
Это не устарело, вы должны использовать файлы .h, если хотите программировать на C. - person Magnus Westin; 19.11.2008