首页 > 解决方案 > #define 中的不断计算会消耗资源吗?

问题描述

就我而言,c/c++ 中的常量和定义不会消耗内存和其他资源,但是当我们将定义用作宏并在其中进行一些计算时,情况就不同了。看一下代码:

#include "math.h"
#define a 12.2
#define b 5.8
#define c a*b
#define d sqrt(c)

当我们在代码中使用变量“d”时,CPU 是否会花费时间来计算 SQRT 和添加操作,或者这些值是在编译器中计算并在代码中替换的?如果它是由 CPU 计算的,那么无论如何都要在预处理器中预先计算并在这里分配为常数?

标签: c++cconstantspreprocessorcalculation

解决方案


就我而言,c/c++ 中的常量和定义不会消耗内存和其他资源,

这取决于你的意思。出现在可能在运行时计算的表达式中的常量必须以某种方式在程序中表示。在大多数情况下,这将占用一些空间。

即使(在 C++ 中) aconstexpr 可以在运行时评估,即使实现可以并且可能确实在编译时评估它们。

但是当我们将定义用作宏并在其中放入一些计算时,情况就不同了。

是的,它是不同的,因为宏在该术语的任何适用意义上都不是常量。

看一下代码:

#include "math.h"
#define a 12.2
#define b 5.8
#define c a*b
#define d sqrt(c)

当我们在代码中使用变量“d”时,

d不是变量。它是一个宏。无论它出现在那些宏定义的范围内,它都完全等同于sqrt(12.2*5.8)出现在该点的表达式。

CPU 是否花费时间来计算 SQRT 和添加操作,或者这个值是在编译器中计算并在代码中替换的?

任何一种都可能发生。这取决于您的编译器,可能取决于编译选项,也可能取决于翻译单元中的其他代码。预计算更有可能在更高的优化级别。

如果它是由 CPU 计算的,那么无论如何都要在预处理器中预先计算并在这里分配为常数?

这样的计算不是预处理器本身语义的一部分。在某种程度上,我们在现代 C 和 C++ 实现中对预处理器和编译器进行了区分,如果执行了预计算,那么它将由编译器执行,而不是由预处理器执行。

C 和 C++ 语言没有定义强制在编译时执行此类评估的机制,但您可以通过提高编译器的优化级别来使其更有可能。或者在 C++ 中,可能有一种方法可以使用模板将表达式包装在constexpr计算其值的函数中,这使得它很可能在编译时被计算。

但是,如果您想要一个常量,那么您始终可以选择手动预先计算它,并定义宏以扩展为实际常量。


推荐阅读