C预处理程序指令是否每次都会重新计算?

问题描述

我有这行代码

#define ALPHABET_SIZE 'z' - 'a' + 1

当我将鼠标悬停在代码中的ALPHABET_SIZE上时,它告诉我它会扩展为'z' - 'a' + 1。 所以我想知道是否每次我在代码中使用ALPHABET_SIZE时都必须重新计算此表达式?如果是这样,如何防止重新计算?

解决方法

#define ALPHABET_SIZE 'z' - 'a' + 1

预处理器替换每个ALPHABET_SIZE

使用

'z' - 'a' + 1

然后,编译器很可能会执行Multi select input in admin site优化,将计算结果替换为26。


演示Constant folding,表达式被26替换为gcc 10.2

,

C标准仅指定程序的可观察行为,而不指定程序的工作方式。

是否每次都重新计算'z' - 'a' + 1不会影响可观察到的行为,因此,由实现决定。

通常,您可以期望明智的编译器在编译时计算结果,尤其是在启用优化的情况下。

,

请考虑以下程序:

postgresql-libs

在我的C实现中,这将打印“ 148”和“ 27”。发生这种情况的原因是,在第一个#define ALPHABET_SIZE 'z' - 'a' + 1 #include <stdio.h> int main(void) { printf("%d\n",2*ALPHABET_SIZE); printf("%d\n",ALPHABET_SIZE*2); } 中,printf2*ALPHABET_SIZE替换为2*'z' - 'a' + 1,而在第二个(2*'z') - 'a' + 1中,{{ 1}}替换为printf,其评估为ALPHABET_SIZE*2。由于它们产生两个不同的结果,因此证明使用C语义的预处理不会用一次计算的单个表达式结果替换宏。它必须产生其他内容(实际上是预处理器令牌的序列),然后在上下文中对其进行重新解释。