You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何C标准禁止源文件以部分预处理token结尾?

关于C标准禁止源文件以部分预处理token结尾的疑问

背景

我正在阅读ISO C标准草案n3096,注意到§5.1.1.2 p1中的明确规定:

源文件被分解为预处理token和空白字符序列(包括注释)。**源文件不得以部分预处理token或部分注释结尾。**每个注释被替换为一个字符。换行字符被保留。除换行外的非空空白字符序列是被保留还是替换为一个空格字符,由实现定义。

该规定从C90及后续各版标准中一直存在。我有两个核心疑问:

  • 为何C标准要明确禁止源文件以部分预处理token结尾?
  • 该规定是否未被其他未定义行为声明覆盖?

我的理解(可能有误)

由于C标准未在其他地方定义“部分预处理token”,我参考了C++标准n4928 §5.2中的信息性脚注:

  1. 部分预处理token会出现在源文件以需要终止字符序列的多字符token的前半部分结尾的情况,例如缺少闭合"或>的header-name……

根据C标准§6.4 p1对preprocessing-token的定义:

preprocessing-token:

  • header-name
  • identifier
  • pp-number
  • character-constant
  • string-literal
  • punctuator
  • 无法归入上述类别的每个通用字符名
  • 无法归入上述类别的每个非空白字符

我认为可形成“部分”状态的预处理token至少包括header-name、character-constant、string-literal以及hexadecimal-floating-constant(一种需要以binary-exponent-part结尾的pp-number)。

我假设该规定并非冗余,而是禁止了其他条款未覆盖的场景:假设非空源文件需以不属于行拼接的换行字符结尾(§5.1.1.2 p1),那么该规定描述的是源文件以不属于行拼接的换行结尾,同时也以部分预处理token结尾的情况——即翻译阶段2后,部分预处理token包含换行。但翻译阶段2后,预处理token本身并不包含换行(/*类型的注释例外,这也是禁止部分注释有实际意义的原因)。

另外我对“部分预处理token”的概念存在困惑:它显然不属于合法的预处理token,但根据preprocessing-token规则中的兜底项(无法归入其他类别的非空白字符单独作为token),似乎不存在“无效”的预处理token。

内容的提问来源于stack exchange,提问作者nore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 04:00:10