Допустим ли обратный слеш в директивах C и C ++ #include? - PullRequest
38 голосов
/ 26 апреля 2011

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

Ответы [ 6 ]

47 голосов
/ 26 апреля 2011

C99 говорит (§6.4.7 / 3):

Если символы ', \, ", // или / * встречаются в последовательности между разделителями <и>, поведение не определено. Аналогично, если встречаются символы', \, // или / * в последовательности между «разделителями» поведение не определено.

(сноска. Таким образом, последовательности символов, которые напоминают escape-последовательности, вызывают неопределенное поведение.)

C ++ 03 говорит (§2.8 / 2):

Если любой из символов или \, или любой из последовательностей символов / * или // появляется в q-char-последовательности или h-char-последовательности, или символ "появляется в h-char-sequence последовательность, поведение не определено.

(сноска. Таким образом, последовательности символов, которые напоминают escape-последовательности, вызывают неопределенное поведение.)

C ++ 11 говорит (§2.9 / 2):

Появление символов или \ или любой последовательности символов / * или // в q-char-последовательности или h-char-последовательности условно поддерживается семантикой, определяемой реализацией, как Появление символа "в h-char-последовательности.

(сноска. Таким образом, последовательность символов, напоминающая escape-последовательность, может привести к ошибке, интерпретироваться как символ, соответствующий escape-последовательности, или иметь совершенно другое значение, в зависимости от реализации.)

Поэтому, хотя любой компилятор может выбрать поддержку обратной косой черты в пути #include, маловероятно, что какой-либо поставщик компилятора не будет поддерживать прямую косую черту, и обратная косая черта, вероятно, приведет к отключению некоторых реализаций благодаря формированию escape-кодов. , (Редактировать: очевидно, MSVC ранее требовал обратной косой черты. Возможно, другие на платформах, производных от DOS, были похожи. Хммм… что я могу сказать.)

C ++ 11 кажется, ослабляет правила, но «условно поддерживаемая» не намного лучше, чем «вызывает неопределенное поведение». Это изменение больше отражает существование некоторых популярных компиляторов, чем описание переносимого стандарта.

Конечно, ни в одном из этих стандартов не говорится, что существует такая вещь, как дорожки. Там есть файловые системы без путей вообще! Однако во многих библиотеках используются имена путей, включая POSIX и Boost, поэтому разумно использовать переносимый способ ссылки на файлы в подкаталогах.

7 голосов
/ 26 апреля 2011

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

6 голосов
/ 26 апреля 2011

Blackslash - неопределенное поведение, и даже с косой чертой вы должны быть осторожны. Стандарт C99 гласит:

Если символы ', \, ", // или / * происходят в последовательности между < и> разделители, поведение не определено. Точно так же, если символы ', \, // или / * встречаются в последовательность между «разделителями», поведение не определено.

5 голосов
/ 12 октября 2011

Это зависит от того, что вы подразумеваете под "приемлемым".

Есть два значения, в которых косые черты допустимы, а обратные косые черты - нет.

Если вы пишете C99, C ++ 03 или C1x, обратная косая черта не определена, в то время как косая черта допустима, поэтому в этом смысле обратная косая черта недопустима.

Но это не имеет значения для большинства людей. Если вы пишете C ++ 1x, где обратная косая черта поддерживается условно, а платформа, для которой вы кодируете, поддерживает их, они приемлемы. И если вы пишете «расширенный диалект» C99 / C ++ 03 / C1x, который определяет обратную косую черту, то же самое. И, что более важно, в любом случае это понятие «приемлемый» в большинстве случаев совершенно бессмысленно. Ни один из стандартов C / C ++ не определяет, что означает косая черта (или что означает обратная косая черта, когда они поддерживаются условно). Имена заголовков сопоставляются с исходными файлами способом, определяемым реализацией, точка. Если у вас есть иерархия файлов, и вы спрашиваете, использовать ли обратную косую черту или косую черту, чтобы ссылаться на них в директивах #include, ответ таков: ни один из них не является переносимым. Если вы хотите написать действительно переносимый код, вы не можете использовать иерархии заголовочных файлов - фактически, возможно, вам лучше всего написать все в одном исходном файле, а не #include ничего, кроме стандартных заголовков.

Однако в реальном мире люди часто хотят, чтобы они были «достаточно портативными», а не «строго портативными». Стандарт POSIX предписывает, что означает косая черта, и даже за пределами POSIX большинство современных платформ, включая Win32 (и Win64), кросс-компиляторы для встраиваемых и мобильных платформ, таких как Symbian и т. Д., Обрабатывают косые черты в POSIX, по крайней мере, настолько, насколько это возможно. C / C ++ #include директивы. Любая платформа, которая не имеет, вероятно, не будет для вас способа вставить на нее дерево исходных текстов, обработать ваш make-файл и т. Д. И т. Д., Поэтому директивы #include будут меньше всего беспокоить вас. Если это то, что вас волнует, то косые черты допустимы, а обратные косые черты - нет.

1 голос
/ 26 апреля 2011

Всегда используйте косую черту - они работают на большем количестве платформ. Обратная косая черта технически вызывает неопределенное поведение в C ++ 03 (2.8 / 2 в стандарте).

0 голосов
/ 26 апреля 2011

Стандарт говорит для #include, что он:

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

Обратите внимание на последнее предложение.

...