首页 > 解决方案 > 编译器对数组声明大小的评估。什么时候发生?

问题描述

这更多是为了清晰或更好地理解编译器的内部工作:我开始研究编译器设计和编译器理论。

通常,在堆栈上声明数组的大小时,必须在编译时知道它,这是可以理解的,但情况并非总是如此。

我想知道的是;何时进行此评估?它是否在预编译器、标记器、语法分析等过程中发生?此外,它是否取决于正在使用的特定编译器?最后,此评估的时间点是否指定为语言标准内编译器的任何特定阶段?

伪代码片段。C 或 C++

int main() {
    int x[5]; // When does the evaluation of the 5 for the array's size take place 
              // during the compilation process? 
              // Does it take place during pre-compiler or normal compilation time. 
    return 0;
}

标签: c++carrayscompiler-constructionsize

解决方案


C 标准规定了翻译的八个阶段:

  1. 物理源多字节字符和三元字符序列映射到源字符集的字符。

  2. 删除后跟换行符的每个反斜杠(将两行拼接在一起)。

  3. 源字符被分组到预处理标记中,并且每个空白字符序列被一个空格替换,除了保留换行符。

  4. 执行预处理指令和 _Pragma 运算符,并扩展宏调用。

  5. 字符串和字符常量中的源字符被转换为执行字符集。

  6. 相邻的字符串文字被连接起来。

  7. 每个预处理标记都被转换为语法标记,并丢弃空格字符分隔的标记。生成的标记被分析和翻译(编译)。

  8. 所有外部引用均已解析(程序已链接)。

因此,恒定阵列尺寸的分辨率发生在阶段 7。然而,这些阶段主要是概念性的。这些阶段解释了如何理解 C 语言,而不是编译器必须如何执行。

对于生成对象模块的编译器,在写入对象信息之前,必须先解决具有静态存储时长的数组大小,因为数组大小会影响数据布局,这必须在对象模块中完整描述。理论上,可以在程序实际执行需要它们的代码之前处理具有自动存储持续时间的数组大小,因为这对于可变长度数组来说是必然的。但是,这样做会很浪费,因为在编译期间很容易处理常量数组大小,并且最好在编译时计算必要的值(例如输入函数时要保留的堆栈空间量),而不是比执行期间。所以我们可以期待普通编译器在编译期间解析所有常量数组大小(也就是说,

翻译过程中解析数组大小的点的附加标识取决于编译器实现(或通常的 C 实现)的内部细节。


推荐阅读