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

Для всех файлов, будь то заголовки проектов или внешние заголовки, всегда используйте шаблон:

#include <namespace/header.hpp>

Пространство имен, по крайней мере, одного каталога, чтобы избежать столкновения.

Конечно, это означает, что каталог проекта, в котором заголовки проекта должны быть добавлены как «default include header» в make-файл, тоже.

Причиной этого выбора является то, что я нашел следующую информацию:

Я дам ответы ниже

1.a Стандарт

Источник:

  • C ++ 14 Рабочий проект n3797: https://isocpp.org/files/papers/N3797.pdf
  • C ++ 11, C ++ 98, C99, C89 (цитируемый раздел не изменяется во всех этих стандартах)

В разделе 16.2 «Ввод исходного файла» мы можем прочитать:

Директива предварительной обработки формы

 #include <h-char-sequence> new-line

ищет последовательность определённых реализацией мест для заголовка, идентифицированного однозначно указанной последовательностью между разделителями <и> и вызывает замену этой директивы на все содержимое заголовка. Как указано места, или идентифицированный заголовок определяется реализацией.

Это означает, что #include <…> будет искать файл в определенной реализации.

Затем следующий параграф:

Директива предварительной обработки формы

 #include "q-char-sequence" new-line

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

 

#include <h-char-sequence> new-line

с идентичной содержащейся последовательностью (включая> символы, если таковые имеются) из исходной директивы.

Это означает, что #include «…» будет искать файл в определенном порядке реализации, а затем, если файл не будет найден, будет выполняться другой поиск, как если бы он был #include <…>

Вывод состоит в том, что мы должны прочитать документацию компиляторов.

Обратите внимание, что по какой-либо причине нигде в стандартах не делается различий между заголовками «system» или «library» или другими заголовками. Единственное отличие в том, что #include <…> похоже, предназначено для заголовков, а #include «…», похоже, предназначено для источника (по крайней мере, в английской формулировке).

1.b Visual C ++:

Источник:

  • http://msdn.microsoft.com/en-us/library/36k2cdd4.aspx

#include «MyFile.hpp»

Препроцессор выполняет поиск включенных файлов в следующем порядке:

  1. В том же каталоге, что и файл, содержащий оператор #include.
  2. В каталогах любых ранее открытых включенных файлов в обратном порядке, в которых они были открыты. Поиск начинается с каталога включенного файла, который был открыт последним, и продолжается через каталог открытого файла, который был открыт первым.
  3. По пути, указанному каждым параметром компилятора / I.
  4. (*) Вдоль путей, заданных переменной среды INCLUDE или включенной по умолчанию средой разработки.

#include <MyFile.hpp>

Препроцессор выполняет поиск включенных файлов в следующем порядке:

  1. По пути, указанному каждым параметром компилятора / I.
  2. (*) Вдоль путей, заданных переменной среды INCLUDE или включенной по умолчанию средой разработки.

Обратите внимание на последний шаг

В документе не ясно, что «Вдоль путей, заданных переменной среды INCLUDE», для части <...> и "..." . Следующая цитата заставляет его придерживаться стандарта:

Для include файлов, которые указаны как #include «path-spec», поиск каталога начинается с каталога родительского файла, а затем проходит через каталоги любых файлов дедушки и бабушки. То есть поиск начинается относительно каталога, содержащего исходный файл, который содержит директиву #include, которая обрабатывается. Если нет файла grandparent и файл не найден, поиск продолжается, как если бы имя файла было заключено в угловые скобки.


Последний шаг (отмеченный звездочкой) является, таким образом, интерпретацией из чтения всего документа.

1.c g ++

Источник:

  • http://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
  • http://gcc.gnu.org/onlinedocs/cpp/Include-Syntax.html
  • http://gcc.gnu.org/onlinedocs/cpp/Include-Operation.html
  • http://gcc.gnu.org/onlinedocs/cpp/Invocation.html
  • http://gcc.gnu.org/onlinedocs/cpp/Search-Path.html
  • http://gcc.gnu.org/onlinedocs/cpp/Once_002dOnly-Headers.html
  • http://gcc.gnu.org/onlinedocs/cpp/Wrapper-Headers.html
  • http://gcc.gnu.org/onlinedocs/cpp/System-Headers.html

Следующая цитата суммирует процесс:

GCC […] будет искать заголовки, запрошенные с #include <file> в [системных каталогах] […] Все каталоги, названные именем -I, выполняются в порядке слева направо перед каталогами по умолчанию

GCC ищет заголовки, запрошенные с #include «file» сначала в каталоге, содержащем текущий файл, затем в каталогах, указанных в параметрах -iquote, а затем в тех же местах он искал заголовок, запрошенный с помощью угловых скобок.

#include «MyFile.hpp»

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


  1. В том же каталоге, что и файл, содержащий оператор #include.
  2. Вдоль пути, заданного параметром -iquote компилятора.
  3. Что касается #include <MyFile.hpp>

#include <MyFile.hpp>

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

  1. По пути, указанному каждым параметром -I компилятора.
  2. Внутри системных каталогов.

1.d Oracle / Sun Studio CC

Источник:

  • http://docs.oracle.com/cd/E19205-01/819-5265/bjadq/index.html

Обратите внимание, что текст несколько противоречит (см. Пример для понимания). Ключевая фраза: « Разница заключается в том, что текущий каталог выполняется только для файлов заголовков, имена которых указаны в кавычках ».

#include «MyFile.hpp»

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

  1. Текущий каталог (то есть каталог, содержащий файл «включая»)
  2. Каталоги, названные с параметрами -I, если они есть
  3. Системный каталог (например, каталог / usr / include)

#include <MyFile.hpp>

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

  1. Каталоги, названные с параметрами -I, если они есть
  2. Системный каталог (например, каталог / usr / include)

1.e Справочник компилятора XL C / C ++ — IBM / AIX

Источник:

  • http://www.bluefern.canterbury.ac.nz/ucsc%20userdocs/forucscwebsite/c/aix/compiler.pdf
  • http://www-01.ibm.com/support/docview.wss?uid=swg27024204&aid=1

Оба документа называются «Справочник компилятора XL C / C ++». Первый документ старше (8,0), но его легче понять. Второй — более новый (12.1), но немного сложнее расшифровать.

#include «MyFile.hpp»

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

  1. Текущий каталог (то есть каталог, содержащий файл «включая»)
  2. Каталоги, названные с параметрами -I, если они есть
  3. Системный каталог (например, директории / usr / vac [cpp] / include или / usr / include)

#include <MyFile.hpp>

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

  1. Каталоги, названные с параметрами -I, если они есть
  2. Системный каталог (например, каталог / usr / vac [cpp] / include или / usr / include)

1.e Заключение

Шаблон «» может привести к точной ошибке компиляции компиляторов, и поскольку в настоящее время я работаю как на Windows Visual C ++, Linux g ++, Oracle / Solaris CC и AIX XL, это неприемлемо.

В любом случае, преимущество «описанных функций» далеко не интересно, так что …

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

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

Использование каталога в include могло бы сэкономить время, потому что пользователю пришлось бы либо написать:

#include <MyLocalProject/Header.hpp>

или

#include <GlobalInclude/Header.hpp>  

Вы заметите, что пока

#include "Header.hpp"

было бы успешно скомпилировано, тем самым, все еще скрывая проблему, тогда как

#include <Header.hpp>

не собирались бы в обычных условиях.

Таким образом, приклеивание к нотации <> сделало бы обязательным для разработчика префикс include с правильным каталогом, еще одна причина предпочесть <> to «».

Используя как обозначение <>, так и именное пространство вместе удаляют из предварительного компилятора возможность угадывать файлы, вместо этого ищут только каталоги включенных по умолчанию.

Конечно, стандартные библиотеки по-прежнему включены как обычно, то есть:

#include <cstdlib> #include <vector>

Директива #include заставляет компилятор прочитать и скомпилировать указанный исходный файл. Для записи этой директивы используются следующие общие формы.


#include "имя_файла"  #include <имя_файла>  

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

#include <MyFuncs.h>  

заставит компилятор прочитать и скомпилировать файл MyFuncs.h.

Если имя файла заключено в угловые скобки, то поиск файла будет осуществляться способом, определенным создателем компилятора. Часто это означает, что поиск выполняется в некотором специальном каталоге, выделенном для заголовочных файлов. Если же имя файла заключено в кавычки, поиск файла выполняется другим способом, зависящим от конкретной реализации. Во многих случаях это означает поиск текущего рабочего каталога. Если заданный файл не найден, поиск повторяется с использованием первого способа (как если бы имя файла было заключено в угловые скобки). Чтобы ознакомиться с подробностями, связанными с различной обработкой директивы #include в случае использования угловых скобок и двойных кавычек, обратитесь к руководству пользователя, прилагаемому к вашему компилятору. Операторы #include могут быть вложенными внутри других включаемых файлов.

Помимо включения файлов, С/С++-программы используют директиву #include для включения заголовков. В языках С и C++ определен набор стандартных заголовков, которые предоставляют информацию, необходимую для различных библиотек (т.е. под заголовком может подразумеваться файл, но это совсем необязательно).


ким образом, заголовок — это просто абстракция, которая гарантирует включение соответствующей информации. Однако на практике С-заголовки почти всегда являются файлами, а имена заголовков — действительными именами файлов. Но для языка C++ ситуация совсем иная. Все имена С++-заголовков представляют собой стандартные идентификаторы, которые компилятор может преобразовать в имена файлов или обработать каким-либо другим способом. А поскольку С++-заголовки не являются именами файлов, они не имеют расширения . п. Например, чтобы включить заголовочную информацию для системы ввода-вывода, используйте следующий оператор.

#include <iostream>

Здесь <iostream> — стандартный заголовок для классов ввода-вывода.

#include Directive (C/C++)

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.

Adblock
detector