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

发布于 2024-11-03 09:41:11 字数 126 浏览 3 评论 0原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

苍白女子 2024-11-10 09:41:11

C99 说(§6.4.7/3):

如果字符 '、\、"、// 或 /* 出现在 < 和 > 分隔符之间的序列中,则行为未定义。同样,如果字符 '、\、// 或 / * 出现在 " 分隔符之间的序列中,行为未定义。

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

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

如果字符 ' 或 \ 或字符序列 /* 或 // 出现在 q-char- 序列或 h-char- 序列中,或者字符 " 出现在 h-char-序列,行为未定义。

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

++11 说(§2.9/2):

q-char-sequence 或 h-char-sequence 中字符 ' 或 \ 或字符序列 /* 或 // 的出现受到实现定义语义的有条件支持,如下所示h-char-sequence 中字符 " 的出现。

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

,尽管任何编译器都可能选择在 #include 路径中支持反斜杠,但任何编译器供应商都不可能不支持正斜杠,并且反斜杠可能会由于形成转义而导致某些实现出错(编辑:显然 MSVC 以前需要反斜杠。也许 DOS 派生平台上的其他平台也类似。嗯……我能说什么。)

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

当然,这些标准中没有任何内容表明存在路径这样的东西。有文件系统根本没有路径!然而,许多库都采用路径名,包括 POSIX 和 Boost,因此需要一种可移植的方式来引用子目录中的文件是合理的。

C99 says (§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):

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.

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

C++11 says (§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.

(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.)

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.

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.

毅然前行 2024-11-10 09:41:11

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

斜杠可以接受而反斜杠则不能接受有两种含义。

如果您正在编写 C99、C++03 或 C1x,反斜杠是未定义的,而斜杠是合法的,因此从这个意义上说,反斜杠是不可接受的。

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

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

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.

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.

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.

痴骨ら 2024-11-10 09:41:11

正斜杠是正确的方法;预编译器将在每个平台上尽一切努力来获取正确的文件。

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

终止放荡 2024-11-10 09:41:11

黑斜杠是未定义的行为,即使使用斜杠你也必须小心。 C99标准规定:

如果字符 '、\、"、// 或 /*
出现在 < 之间的序列中
和>分隔符,行为是
不明确的。同样,如果
字符 '、\、// 或 /* 出现在
" 分隔符之间的顺序,
行为未定义。

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

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.

摘星┃星的人 2024-11-10 09:41:11

始终使用正斜杠 - 它们适用于更多平台。从技术上讲,反斜杠会导致 C++03(标准中的 2.8/2)中出现未定义的行为。

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

薄暮涼年 2024-11-10 09:41:11

该标准对 #include 的规定是:

搜索一系列实现定义的位置
由之间的指定序列唯一标识的标头
分隔符,并导致将该指令替换为
标题的全部内容。如何指定地点或标题
确定是实现定义的。

注意最后一句。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文