C和c++ #include指令可以接受反斜杠吗?

时间:2023-01-13 09:45:31

There are two path separators in common use: the Unix forward-slash and the DOS backslash. Rest in peace, Classic Mac colon. If used in an #include directive, are they equal under the rules of the C++11, C++03, and C99 standards?

有两种常用的路径分隔符:Unix正斜杠和DOS反斜杠。安息吧,经典的Mac冒号。如果在#include指令中使用,它们在c++ 11、c++ 03和C99标准下是否相等?

6 个解决方案

#1


44  

C99 says (§6.4.7/3):

C99说(§6.4.7/3):

If the characters ', \, ", //, or /* occur in the sequence between the < and > delimiters, the behavior is undefined. Similarly, if the characters ', \, //, or /* occur in the sequence between the " delimiters, the behavior is undefined.

如果字符'、\ "、/或/*出现在 <和> 分隔符之间的序列中,则该行为没有定义。类似地,如果字符、\、/或/*发生在“分隔符”之间的序列中,则行为是未定义的。

(footnote: Thus, sequences of characters that resemble escape sequences cause undefined behavior.)

(脚注:因此,类似转义序列的字符序列会导致未定义的行为。)

C++03 says (§2.8/2):

c++ 03说(§2.8 / 2):

If either of the characters ’ or \, or either of the character sequences /* or // appears in a q-char- sequence or a h-char-sequence, or the character " appears in a h-char-sequence, the behavior is undefined.

如果字符的'或\,或字符序列/*或//中的任何一个出现在q-char- sequence或h- ha -sequence中,或者字符“出现在h- ha -sequence中,则该行为未定义。

(footnote: Thus, sequences of characters that resemble escape sequences cause undefined behavior.)

(脚注:因此,类似转义序列的字符序列会导致未定义的行为。)

C++11 says (§2.9/2):

c++ 11说(§2.9 / 2):

The appearance of either of the characters ’ or \ or of either of the character sequences /* or // in a q-char-sequence or an h-char-sequence is conditionally supported with implementation-defined semantics, as is the appearance of the character " in an h-char-sequence.

在一个q-char-sequence或一个h- ha -sequence中,字符的或\或字符序列/*或/的出现都有条件地得到实现定义语义的支持,就像在一个h- ha -sequence中出现字符“一样。

(footnote: Thus, a sequence of characters that resembles an escape sequence might result in an error, be interpreted as the character corresponding to the escape sequence, or have a completely different meaning, depending on the implementation.)

(脚注:因此,一个类似于转义序列的字符序列可能会导致错误,被解释为与转义序列对应的字符,或者有完全不同的含义,取决于实现。)

Therefore, although any compiler might choose to support a backslash in a #include path, it is unlikely that any compiler vendor won't support forward slash, and backslashes are likely to trip some implementations up by virtue of forming escape codes. (Edit: apparently MSVC previously required backslash. Perhaps others on DOS-derived platforms were similar. Hmmm… what can I say.)

因此,尽管任何编译器都可能选择在#include路径中支持反斜杠,但是任何编译器厂商都不太可能不支持正斜杠,而且反斜杠很可能会由于形成转义代码而导致某些实现出错。(编辑:显然MSVC之前需要反斜杠。也许在dos平台上的其他平台也很相似。我能说什么呢?

C++11 seems to loosen the rules, but "conditionally supported" is not meaningfully better than "causes undefined behavior." The change does more to reflect the existence of certain popular compilers than to describe a portable standard.

c++ 11似乎放宽了规则,但“有条件支持”并不比“导致未定义行为”更好。这种变化更多地反映了某些流行编译器的存在,而不是描述一个可移植的标准。

Of course, nothing in any of these standards says that there is such a thing as paths. There are filesystems out there with no paths at all! However, many libraries assume pathnames, including POSIX and Boost, so it is reasonable to want a portable way to refer to files within subdirectories.

当然,在这些标准中,没有任何一项是说有路径这样的东西。那里有文件系统,根本没有路径!但是,许多库都假定有路径名,包括POSIX和Boost,因此需要一种可移植的方式来引用子目录中的文件。

#2


7  

Forward slash is the correct way; the pre-compiler will do whatever it takes on each platform to get to the correct file.

正斜杠是正确的方法;预编译器将在每个平台上执行任何操作以获得正确的文件。

#3


5  

Blackslash is undefined behavior and even with a slash you have to be careful. The C99 standard states:

Blackslash是未定义的行为,即使是一个斜杠,你也要小心。C99标准:

If the characters ', \, ", //, or /* occur in the sequence between the < and > delimiters, the behavior is undefined. Similarly, if the characters ', \, //, or /* occur in the sequence between the " delimiters, the behavior is undefined.

如果字符'、\ "、/或/*出现在 <和> 分隔符之间的序列中,则该行为没有定义。类似地,如果字符、\、/或/*发生在“分隔符”之间的序列中,则行为是未定义的。

#4


5  

It depends on what you mean by "acceptable".

这取决于你所说的“可接受”是什么意思。

There are two senses in which slashes are acceptable and backslashes are not.

有两种感觉,斜杠是可以接受的,反斜杠是不能接受的。

If you're writing C99, C++03, or C1x, backslashes are undefined, while slashes are legal, so in this sense, backslashes are not acceptable.

如果您正在编写C99、c++ 03或C1x,那么反斜杠是没有定义的,而反斜杠是合法的,因此在这个意义上,反斜杠是不可接受的。

But this is irrelevant for most people. If you're writing C++1x, where backslashes are conditionally-supported, and the platform you're coding for supports them, they're acceptable. And if you're writing an "extended dialect" of C99/C++03/C1x that defines backslashes, same deal. And, more importantly, this notion of "acceptable" is pretty meaningless in most cases anyway. None of the C/C++ standards define what slashes mean (or what backslashes mean when they're conditionally-supported). Header names are mapped to source files in an implementation-defined manner, period. If you've got a hierarchy of files, and you're asking whether to use backslashes or slashes to refer to them portably in #include directives, the answer is: neither is portable. If you want to write truly portable code, you can't use hierarchies of header files—in fact, arguably, your best bet is to write everything in a single source file, and not #include anything except standard headers.

但这与大多数人无关。如果您正在编写c++ 1x,其中反斜杠是受条件支持的,并且您正在编写的平台支持它们,那么它们是可以接受的。如果你在写C99/C+ 03/C1x的“扩展方言”来定义反斜线,也一样。更重要的是,“可接受”的概念在大多数情况下都毫无意义。没有任何C/ c++标准定义了斜杠的含义(或者当它们受到条件支持时,斜杠的含义是什么)。头名以实现定义的方式、周期映射到源文件。如果您有一个文件层次结构,并且您正在询问是否使用反斜杠或斜杠在#include指令中以可移植性的方式引用它们,那么答案是:两者都不是可移植的。如果您想编写真正可移植的代码,您就不能使用头文件的层次结构—事实上,可以说,您的最佳选择是将所有内容编写在一个源文件中,而不是#包含除标准头之外的任何内容。

However, in the real world, people often want "portable-enough", not "strictly portable". The POSIX standard mandates what slashes mean, and even beyond POSIX, most modern platforms—including Win32 (and Win64), the cross-compilers for embedded and mobile platforms like Symbian, etc.—treat slashes the POSIX way, at least as far as C/C++ #include directives. Any platform that doesn't, probably won't have any way for you to get your source tree onto it, process your makefile/etc., and so on, so #include directives will be the least of your worries. If that's what you care about, then slashes are acceptable, but backslashes are not.

然而,在现实世界中,人们往往想要“足够便携”,而不是“完全便携”。POSIX标准规定了slashes的含义,甚至超过POSIX,大多数现代平台,包括Win32(和Win64),嵌入式和移动平台(如Symbian等)的交叉编译器等等。-处理对POSIX方式的斜杠,至少在C/ c++ #中包含指令。任何平台如果没有,可能都无法将源代码树放到它上面,处理您的makefile/等等。,等等,所以#include指令将是您最不担心的。如果这是你所关心的,那么斜杠是可以接受的,但是反斜杠不是。

#5


0  

The standard says for #include that it:

对于#的标准是:

searches a sequence of implementation-defined places for a header identified uniquely by the specified sequence between the delimiters, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined.

搜索一个实现定义的位置序列,查找由分隔符之间的指定序列唯一标识的头,并导致该指令被头的整个内容替换。如何指定位置或标识头是由实现定义的。

Note the last sentence.

注意最后一句话。

#6


0  

Always use forward slashes - they work on more platforms. Backslash technically causes undefined behaviour in C++03 (2.8/2 in the standard).

总是使用前斜杠——它们在更多的平台上工作。从技术上讲,反斜杠导致c++ 03中的未定义行为(标准中为2.8/2)。

#1


44  

C99 says (§6.4.7/3):

C99说(§6.4.7/3):

If the characters ', \, ", //, or /* occur in the sequence between the < and > delimiters, the behavior is undefined. Similarly, if the characters ', \, //, or /* occur in the sequence between the " delimiters, the behavior is undefined.

如果字符'、\ "、/或/*出现在 <和> 分隔符之间的序列中,则该行为没有定义。类似地,如果字符、\、/或/*发生在“分隔符”之间的序列中,则行为是未定义的。

(footnote: Thus, sequences of characters that resemble escape sequences cause undefined behavior.)

(脚注:因此,类似转义序列的字符序列会导致未定义的行为。)

C++03 says (§2.8/2):

c++ 03说(§2.8 / 2):

If either of the characters ’ or \, or either of the character sequences /* or // appears in a q-char- sequence or a h-char-sequence, or the character " appears in a h-char-sequence, the behavior is undefined.

如果字符的'或\,或字符序列/*或//中的任何一个出现在q-char- sequence或h- ha -sequence中,或者字符“出现在h- ha -sequence中,则该行为未定义。

(footnote: Thus, sequences of characters that resemble escape sequences cause undefined behavior.)

(脚注:因此,类似转义序列的字符序列会导致未定义的行为。)

C++11 says (§2.9/2):

c++ 11说(§2.9 / 2):

The appearance of either of the characters ’ or \ or of either of the character sequences /* or // in a q-char-sequence or an h-char-sequence is conditionally supported with implementation-defined semantics, as is the appearance of the character " in an h-char-sequence.

在一个q-char-sequence或一个h- ha -sequence中,字符的或\或字符序列/*或/的出现都有条件地得到实现定义语义的支持,就像在一个h- ha -sequence中出现字符“一样。

(footnote: Thus, a sequence of characters that resembles an escape sequence might result in an error, be interpreted as the character corresponding to the escape sequence, or have a completely different meaning, depending on the implementation.)

(脚注:因此,一个类似于转义序列的字符序列可能会导致错误,被解释为与转义序列对应的字符,或者有完全不同的含义,取决于实现。)

Therefore, although any compiler might choose to support a backslash in a #include path, it is unlikely that any compiler vendor won't support forward slash, and backslashes are likely to trip some implementations up by virtue of forming escape codes. (Edit: apparently MSVC previously required backslash. Perhaps others on DOS-derived platforms were similar. Hmmm… what can I say.)

因此,尽管任何编译器都可能选择在#include路径中支持反斜杠,但是任何编译器厂商都不太可能不支持正斜杠,而且反斜杠很可能会由于形成转义代码而导致某些实现出错。(编辑:显然MSVC之前需要反斜杠。也许在dos平台上的其他平台也很相似。我能说什么呢?

C++11 seems to loosen the rules, but "conditionally supported" is not meaningfully better than "causes undefined behavior." The change does more to reflect the existence of certain popular compilers than to describe a portable standard.

c++ 11似乎放宽了规则,但“有条件支持”并不比“导致未定义行为”更好。这种变化更多地反映了某些流行编译器的存在,而不是描述一个可移植的标准。

Of course, nothing in any of these standards says that there is such a thing as paths. There are filesystems out there with no paths at all! However, many libraries assume pathnames, including POSIX and Boost, so it is reasonable to want a portable way to refer to files within subdirectories.

当然,在这些标准中,没有任何一项是说有路径这样的东西。那里有文件系统,根本没有路径!但是,许多库都假定有路径名,包括POSIX和Boost,因此需要一种可移植的方式来引用子目录中的文件。

#2


7  

Forward slash is the correct way; the pre-compiler will do whatever it takes on each platform to get to the correct file.

正斜杠是正确的方法;预编译器将在每个平台上执行任何操作以获得正确的文件。

#3


5  

Blackslash is undefined behavior and even with a slash you have to be careful. The C99 standard states:

Blackslash是未定义的行为,即使是一个斜杠,你也要小心。C99标准:

If the characters ', \, ", //, or /* occur in the sequence between the < and > delimiters, the behavior is undefined. Similarly, if the characters ', \, //, or /* occur in the sequence between the " delimiters, the behavior is undefined.

如果字符'、\ "、/或/*出现在 <和> 分隔符之间的序列中,则该行为没有定义。类似地,如果字符、\、/或/*发生在“分隔符”之间的序列中,则行为是未定义的。

#4


5  

It depends on what you mean by "acceptable".

这取决于你所说的“可接受”是什么意思。

There are two senses in which slashes are acceptable and backslashes are not.

有两种感觉,斜杠是可以接受的,反斜杠是不能接受的。

If you're writing C99, C++03, or C1x, backslashes are undefined, while slashes are legal, so in this sense, backslashes are not acceptable.

如果您正在编写C99、c++ 03或C1x,那么反斜杠是没有定义的,而反斜杠是合法的,因此在这个意义上,反斜杠是不可接受的。

But this is irrelevant for most people. If you're writing C++1x, where backslashes are conditionally-supported, and the platform you're coding for supports them, they're acceptable. And if you're writing an "extended dialect" of C99/C++03/C1x that defines backslashes, same deal. And, more importantly, this notion of "acceptable" is pretty meaningless in most cases anyway. None of the C/C++ standards define what slashes mean (or what backslashes mean when they're conditionally-supported). Header names are mapped to source files in an implementation-defined manner, period. If you've got a hierarchy of files, and you're asking whether to use backslashes or slashes to refer to them portably in #include directives, the answer is: neither is portable. If you want to write truly portable code, you can't use hierarchies of header files—in fact, arguably, your best bet is to write everything in a single source file, and not #include anything except standard headers.

但这与大多数人无关。如果您正在编写c++ 1x,其中反斜杠是受条件支持的,并且您正在编写的平台支持它们,那么它们是可以接受的。如果你在写C99/C+ 03/C1x的“扩展方言”来定义反斜线,也一样。更重要的是,“可接受”的概念在大多数情况下都毫无意义。没有任何C/ c++标准定义了斜杠的含义(或者当它们受到条件支持时,斜杠的含义是什么)。头名以实现定义的方式、周期映射到源文件。如果您有一个文件层次结构,并且您正在询问是否使用反斜杠或斜杠在#include指令中以可移植性的方式引用它们,那么答案是:两者都不是可移植的。如果您想编写真正可移植的代码,您就不能使用头文件的层次结构—事实上,可以说,您的最佳选择是将所有内容编写在一个源文件中,而不是#包含除标准头之外的任何内容。

However, in the real world, people often want "portable-enough", not "strictly portable". The POSIX standard mandates what slashes mean, and even beyond POSIX, most modern platforms—including Win32 (and Win64), the cross-compilers for embedded and mobile platforms like Symbian, etc.—treat slashes the POSIX way, at least as far as C/C++ #include directives. Any platform that doesn't, probably won't have any way for you to get your source tree onto it, process your makefile/etc., and so on, so #include directives will be the least of your worries. If that's what you care about, then slashes are acceptable, but backslashes are not.

然而,在现实世界中,人们往往想要“足够便携”,而不是“完全便携”。POSIX标准规定了slashes的含义,甚至超过POSIX,大多数现代平台,包括Win32(和Win64),嵌入式和移动平台(如Symbian等)的交叉编译器等等。-处理对POSIX方式的斜杠,至少在C/ c++ #中包含指令。任何平台如果没有,可能都无法将源代码树放到它上面,处理您的makefile/等等。,等等,所以#include指令将是您最不担心的。如果这是你所关心的,那么斜杠是可以接受的,但是反斜杠不是。

#5


0  

The standard says for #include that it:

对于#的标准是:

searches a sequence of implementation-defined places for a header identified uniquely by the specified sequence between the delimiters, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined.

搜索一个实现定义的位置序列,查找由分隔符之间的指定序列唯一标识的头,并导致该指令被头的整个内容替换。如何指定位置或标识头是由实现定义的。

Note the last sentence.

注意最后一句话。

#6


0  

Always use forward slashes - they work on more platforms. Backslash technically causes undefined behaviour in C++03 (2.8/2 in the standard).

总是使用前斜杠——它们在更多的平台上工作。从技术上讲,反斜杠导致c++ 03中的未定义行为(标准中为2.8/2)。