GCC 的尖括号实现包括。为什么一定要像下面描述的那样?

GCC's implementation of angle-brackets includes. Why does it have to be as described below?

This document 在其 2.6 Computed Includes 部分中有以下段落:

If the line expands to a token stream beginning with a < token and including a >  token, then the tokens between the <  and the first > are combined to form the filename to be included. Any whitespace between tokens is reduced to a single space; then any space after the initial < is retained, but a trailing space before the closing > is ignored. CPP searches for the file according to the rules for angle-bracket includes.

我知道这是实现定义的,但为什么 GCC 必须这样?我指的是上面突出显示的句子。

编辑

我刚刚注意到上面引用的那段之前的第三段是这样说的:

You must be careful when you define the macro. #define saves tokens, not text. The preprocessor has no way of knowing that the macro will be used as the argument of #include, so it generates ordinary tokens, not a header name. This is unlikely to cause problems if you use double-quote includes, which are close enough to string constants. If you use angle brackets, however, you may have trouble.

有谁知道这里指出的问题是什么?

估计是实现者在实现这个功能的时候选择了最简单的方式,没有考虑太多。

最初的实施似乎是在 2000 年 7 月 3 日(二十年前!)。相关部分看起来像 (source):

  for (;;)
    {
      t = cpp_get_token (pfile);
      if (t->type == CPP_GREATER || t->type == CPP_EOF)
        break;

      CPP_RESERVE (pfile, TOKEN_LEN (t));
      if (t->flags & PREV_WHITE)
        CPP_PUTC_Q (pfile, ' ');
      pfile->limit = spell_token (pfile, t, pfile->limit);
    }

值得注意的是,它在看到 CPP_GREATER 令牌(即 >)时爆发, 为令牌保留内存之前。这是有道理的,因为当令牌不会被写入缓冲区时不需要分配内存。

然后,只有after内存被保留,预处理器检查token前面是否有空格(t->flags & PREV_WHITE),如果有,就写入一个空格字符到缓冲区。

因此,在< foo / bar >中,只有foo之前的空格(即开头的<之后)、/bar ] 被保留。