使用#include指令尾随字符

时间:2015-08-14 11:25:30

标签: c language-lawyer c-preprocessor code-formatting

我在源文件中有一条看似无关紧要的行

#include <some_sys_header_file.h>"

它被一堆其他的包括使用双引号(而不是尖括号)所掩盖,因此没有发现虚假的双引号。

编译器(或者更确切地说,预处理器)很高兴,包含了所需的文件,并跳过了其余部分。

但是,在使用Artistic Style格式化文件时,双引号导致文字字符串被错误地分割为多行的混乱。

是否应该如何对待这个标准?

2 个答案:

答案 0 :(得分:6)

未定义的行为

C99在6.10中说#include指令的格式为

# include pp-tokens new-line

"开头的唯一pp-tokens是字符串文字(C99 6.4.5 字符串文字)和双引号中的标题名称(C99 6.4.7 标题名称)。但是,字符串文字不得包含未转义的换行符,并且标题名称不得包含换行符。 单独的"也不能成为标题名称的一部分,因为它不在<>内(C99 6.4.7 标题名称)。 根据C99 6.4 词汇元素剩下的是

  

预处理令牌
          ...
          每个非空白字符都不能是上述

之一

与第3段中的语义结合使用

  

如果'"字符与最后一个类别匹配,则行为为   未定义。

所以你可能会或可能不会得到诊断。

答案 1 :(得分:0)

当编写标准时,一些编译器在#include参数上没有使用正常的字符串解析逻辑(特别是在其他任何地方都没有使用的角括号形式)。由于关闭角括号不应该跟白色空间以外的任何东西,因此编译器只需擦除最后一个非whitepsace字符(应该是一个尖括号)而不检查它是什么是合理的。 ,并使用它之前的任何内容作为文件名。这,编译器可以考虑:

#include <stdio.h> Hey

作为包含名为stdio.h> He的文件的请求。虽然该特定行为可能没有用,但假设在使用>作为路径分隔符的环境中使用C,可能因此需要:

#include <graphlib>drawing.h>

由于在预期的标题名称之后包含字符可能会导致编译器#include以外的文件,并且因为这样的文件可以做任何事情,所以包括除标准定义的指令之外的包含指令未定义的行为。就个人而言,我认为如果另外一种形式标准化,语言会受益匪浅:

#include "literal1" "literal2" ["literal3", etc.]

以通常的方式应用字符串连接。我曾经合作过的许多项目都有非常长的包含路径列表,如果可以这么说,可以大大减轻这些需求:

#include "fooproject_directories.h"
#include ACMEDIR "acme.h"
#include IOSYSDIR "io.h"

等。从而明确哪些文件应该从哪里加载。虽然有些代码可能依赖于能够说:

#include "this"file.h"

作为加载名为this"file.h的文件的一种方法我认为标准可以通过将这些处理视为非规范性来容纳这些事情,要求任何实施都记录这种非规范性行为,并且不要求严格 - 在这些非规范性平台上运作的合规程序。