C 和 C++ 中可以接受反斜杠吗? #include 指令?
有两种常用的路径分隔符: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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
C99 说(§6.4.7/3):
C++03 说(§2.8/2):
++11 说(§2.9/2):
,尽管任何编译器都可能选择在
#include
路径中支持反斜杠,但任何编译器供应商都不可能不支持正斜杠,并且反斜杠可能会由于形成转义而导致某些实现出错(编辑:显然 MSVC 以前需要反斜杠。也许 DOS 派生平台上的其他平台也类似。嗯……我能说什么。)C++11 似乎放宽了规则,但“有条件支持” “ 没有意义比“导致未定义的行为”更好。该更改更多地反映了某些流行编译器的存在,而不是描述可移植标准。
当然,这些标准中没有任何内容表明存在路径这样的东西。有文件系统根本没有路径!然而,许多库都采用路径名,包括 POSIX 和 Boost,因此需要一种可移植的方式来引用子目录中的文件是合理的。
C99 says (§6.4.7/3):
C++03 says (§2.8/2):
C++11 says (§2.9/2):
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.
这取决于你所说的“可接受”是什么意思。
斜杠可以接受而反斜杠则不能接受有两种含义。
如果您正在编写 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.
正斜杠是正确的方法;预编译器将在每个平台上尽一切努力来获取正确的文件。
Forward slash is the correct way; the pre-compiler will do whatever it takes on each platform to get to the correct file.
黑斜杠是未定义的行为,即使使用斜杠你也必须小心。 C99标准规定:
Blackslash is undefined behavior and even with a slash you have to be careful. The C99 standard states:
始终使用正斜杠 - 它们适用于更多平台。从技术上讲,反斜杠会导致 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).
该标准对 #include 的规定是:
注意最后一句。
The standard says for #include that it:
Note the last sentence.