Подтвердить что ты не робот

Является ли обратная косая черта приемлемой в директивах C и С++ #include?

Существует два разделителя пути: Unix forward-slash и обратная косая черта DOS. Оставайтесь в покое, двоеточие Classic Mac. Если они используются в директиве #include, они равны по правилам С++ 11, С++ 03 и C99 стандарты?

4b9b3361

Ответ 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 в стандарте).