Существует два разделителя пути: Unix forward-slash и обратная косая черта DOS. Оставайтесь в покое, двоеточие Classic Mac. Если они используются в директиве #include, они равны по правилам С++ 11, С++ 03 и C99 стандарты?
Является ли обратная косая черта приемлемой в директивах C и С++ #include?
Ответ 1
C99 говорит (§6.4.7/3):
Если символы ', \, ",//или/* встречаются в последовательности между разделителями < и > , поведение undefined. Аналогично, если символы', \,//или/* встречаются в последовательности между" разделителями", поведение undefined.
(сноска: Таким образом, последовательности символов, которые напоминают escape-последовательности, вызывают поведение undefined.)
С++ 03 говорит (§2.8/2):
Если любой из символов или\или любая из последовательностей символов /* или//появляется в последовательности q- char или h-char -последовательности, или символ "появляется в h - char -последовательность, поведение undefined.
(сноска: Таким образом, последовательности символов, которые напоминают escape-последовательности, вызывают поведение undefined.)
С++ 11 говорит (§2.9/2):
Появление любого из символов или\или любой из последовательностей символов /* или//в q- char -последовательности или h-char -последовательности условно поддерживается семантикой, определенной реализацией, как и появление символа "в h- char -последовательности.
(сноска: Таким образом, последовательность символов, которая напоминает escape-последовательность, может привести к ошибке, интерпретироваться как символ, соответствующий escape-последовательности, или иметь совершенно другое значение в зависимости от реализации.)
Поэтому, хотя любой компилятор может предпочесть поддерживать обратную косую черту в пути #include
, маловероятно, что какой-либо поставщик компилятора не будет поддерживать косую черту в обратном направлении, а обратные сляки, скорее всего, отключат некоторые реализации в результате формирования escape-кодов, (Edit: по-видимому, MSVC ранее требовала обратной косой черты. Возможно, другие на платформах DOS были похожи. Хммм... что я могу сказать.)
С++ 11, похоже, ослабляет правила, но "условно поддерживается" не имеет смысла лучше, чем "вызывает поведение undefined". Это изменение в большей степени отражает существование некоторых популярных компиляторов, чем описание портативного стандарта.
Конечно, ничто в любом из этих стандартов не говорит о том, что есть такие вещи, как пути. Есть файловые системы там, где нет путей! Тем не менее, многие библиотеки предполагают имена путей, включая POSIX и Boost, поэтому разумно хотеть, чтобы переносимый способ ссылаться на файлы в подкаталогах.
Ответ 2
Прямая косая черта - правильный путь; предварительный компилятор будет делать все, что требуется для каждой платформы, чтобы добраться до нужного файла.
Ответ 3
Blackslash - это поведение undefined, и даже с косой чертой вы должны быть осторожны. Стандарт C99 гласит:
Если символы ', \, ",//или/* происходят в последовательности между < и > разделителей, поведение undefined. Аналогично, если символы ', \,//или/* встречаются в последовательность между" разделителями", поведение undefined.
Ответ 4
Это зависит от того, что вы подразумеваете под "приемлемым".
Есть два чувства, в которых слэши приемлемы, а обратные косые черты - нет.
Если вы пишете C99, С++ 03 или C1x, обратные косые черты undefined, а косые черты законны, поэтому в этом смысле обратные косые черты неприемлемы.
Но это не имеет значения для большинства людей. Если вы пишете С++ 1x, где обратная косая черта условно поддерживается, а платформа, которую вы кодируете для поддержки, приемлема. И если вы пишете "расширенный диалект" C99/С++ 03/C1x, который определяет обратную косую черту, то же самое. И, что более важно, это понятие "приемлемый" в большинстве случаев практически не имеет смысла. Ни один из стандартов C/С++ не определяет, что означает слэш (или что означает обратная косая черта, когда они условно поддерживаются). Имена заголовков сопоставляются с исходными файлами в порядке реализации, периоде. Если у вас есть иерархия файлов, и вы спрашиваете, следует ли использовать обратную косую черту или слэши, чтобы ссылаться на них в переносимости в директивах #include, ответ таков: ни один из них не является переносимым. Если вы хотите написать действительно портативный код, вы не можете использовать иерархии файлов заголовков - на самом деле, возможно, лучше всего писать все в одном исходном файле, а не # включать что-либо, кроме стандартных заголовков.
Однако в реальном мире люди часто хотят "портативного достаточно", а не "строго переносного". В стандарте POSIX указано, что означают сокращения и даже за пределами POSIX, большинство современных платформ, включая Win32 (и Win64), кросс-компиляторы для встроенных и мобильных платформ, таких как Symbian и т.д., Обрабатывают POSIX-путь, по крайней мере, до Директивы C/С++ #include. Любая платформа, которая этого не делает, вероятно, не будет иметь для вас возможности получить исходное дерево, обработать ваш makefile/etc. И т.д., Поэтому директивы #include будут наименьшим из ваших забот. Если это то, о чем вы заботитесь, тогда косые черты приемлемы, но обратные косые черты не являются.
Ответ 5
В стандарте указано, что #include:
выполняет поиск последовательности определённых реализацией мест для заголовок, идентифицированный однозначно по указанной последовательности между делителей, и вызывает замену этой директивы всего содержимого заголовка. Как указаны места или заголовок определяется как реализация.
Обратите внимание на последнее предложение.
Ответ 6
Всегда использовать косые черты - они работают на других платформах. Обратная черта технически вызывает поведение undefined в С++ 03 (2.8/2 в стандарте).