【问题标题】:confused about compile time constants对编译时常量感到困惑
【发布时间】:2020-08-01 15:30:46
【问题描述】:

正如我在一本 C++ 书籍中看到的,gcc 的过程是:预处理、Compiling、组装和链接。

Compile Time 常量和Run Time 常量。然后我对“编译”和“编译时间”感到困惑。请告诉我gcc过程中的“编译时间”是什么意思,是Pre-Processing,Compiling,Assembling and Linking的全部吗?

【问题讨论】:

  • 我认为这些术语没有固定的含义。编译时间通常与运行时间形成对比,因此从这个意义上说,编译时间就像您所说的那样。
  • C++ 确实区分了编译时常量和运行时常量。请参阅下面的答案
  • 如果有什么对您没有意义,请告诉我。我很乐意详细说明。对于学习 C++ 和/或增强他们的语言知识的人们来说,这些是重要的概念。

标签: c++ gcc compilation linker constants


【解决方案1】:

“编译时间”或“编译”是该过程的一部分。在 C++ 中,有一个称为宏的功能在预处理器阶段扩展为 C++ 代码。这个预处理器阶段首先在编译器之前运行。根据编译器的不同,下一步是将人类可读的 C++ 代码转换为机器可读的另一种形式。这实际上取决于编译器的类型和编译期间传入的其他可能参数,以了解它变成了什么。为简单起见,我们假设编译器将 C++ 编译为符号/程序集/机器代码。这些文件中的每一个都是独立的,因为没有更好的术语。

最后一步是将这些链接在一起。包含、前向声明和外部声明在此阶段得到解决。曾经独立的文件现在与阶段结束时已知的类型/类/结构的大小“链接”。完成所有这些之后,就会形成一个可执行文件,该可执行文件是纯粹的机器语言,并且运行该程序的计算机可以理解该可执行文件。

C++ 编程的一般经验法则是,您希望在编译时捕获尽可能多的错误。运行时是您的程序执行机器代码的时间跨度。这可以包括堆分配、动态列表调整大小等......

现在,你的问题的症结所在。 Run-Time 常量和 Compile Time 常量有什么区别?这很简单。 编译时间 常量是编译时已知和可解析的值。这些值可以确定和计算,并且不依赖于外部用户输入或文件数据。请参阅 constexpr 作为了解有关编译时间常量的更多信息的良好参考:ConstExprLink

const int userScore = 3; // Compile time constant
const int secondUserScore = 5; // Compile time constant
constexpr int CombinedUserScores = ( userScore + secondUserScore ); // Also compile constant because all values are known at compile time   

但是,有些常量在编译时是无法知道的。这些值可以在您的程序Run-Time 开始后确定和解析。现在,相比之下,假设您在运行时从文件中读取用户输入或数据

std::cout << "Enter your Test Score: ";
const int testScore = 0;
std::cin >> testScore; // User sets an input value during Run-Time

const int userScore { testScore }; // Run-Time constant. No way to know the value at compile time

userScore 现在是一个运行时常量,除非您使用一些禁忌的东西,例如 const_cast 或 C 样式转换,否则无法更改。这里的要点是,在读入输入之前,编译器无法知道这个常量的值是多少。这通常称为数据驱动编程,是一种非常常见的范例。此外,由于 Run-Time const 不是在编译时确定的,因此此处不能使用 constexpr

以上是 Run-Time 常量的示例。此值无法在编译时解析,因为编译器不知道来自用户或文件的输入可能是什么。这是另一个很好的参考:CompileTimeConstant Versus RunTimeConstant

【讨论】:

    【解决方案2】:

    您描述的不同步骤如下:

    预处理:这只是文本被替换的时候。例如,当您#include 一个标头时,该文件的全部内容会直接转储到该位置。预处理也可用于使用#define 制作“编译时常量”,但这不是现代 C++ 的推荐做法。

    编译:为了简单地解释这一点(这有很多细微差别),这是当您的代码被转换为您正在编译的架构的机器指令时。 p>

    组装/链接:这些与问题有些无关,但它们是将程序的各个部分组合在一起以生成可执行文件的最后一步。

    这个问题要求的内容有些含糊,但对于一般的常量,运行时意味着它们是在程序启动后创建的,编译时意味着它们是在程序启动之前预先计算的(当代码正在编译)。现代 C++ 引入了constexpr,它允许您明确声明某些内容应该在编译时初始化,并且能够在编译时计算中传递。

    以数字 pi 为例。计算到第 20 位需要一点时间,但如果它被声明为编译时间常数(例如constexpr double pi = 3.14159...),它是免费的,也可以与任何编译时间计算混合使用。这类东西在最新标准中得到了很大的扩展。

    运行时常量不能用于编译时计算,因为它们的值在编译时是未知的。 const 用作强制某些变量不能更改的约束,在函数参数中很常见以接受只读引用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多