C 预处理器指令是否每次都重新计算?
Does C preprocessor directives recompute each time?
我有这行代码:
#define ALPHABET_SIZE 'z' - 'a' + 1
当我将鼠标悬停在代码中的 ALPHABET_SIZE 上时,它告诉我它扩展到 'z' - 'a' + 1
。
所以我想知道是否每次在我的代码中使用 ALPHABET_SIZE 时都必须重新计算这个表达式?如果是这样,我怎样才能防止重新计算?
C 标准仅指定程序的可观察行为,而不是它们在幕后的工作方式。
是否每次都重新计算 'z' - 'a' + 1
不会影响可观察到的行为,因此由实现决定。
一般来说,您可以期待明智的编译器在 compile-time 处计算结果,尤其是在启用优化时。
#define ALPHABET_SIZE 'z' - 'a' + 1
pre-processor替换每个ALPHABET_SIZE
有
'z' - 'a' + 1
然后编译器很可能会执行 Constant folding 优化,用 26 替换计算。
Demo https://godbolt.org/z/Mo46db,表达式被26
替换为gcc 10.2
考虑以下程序:
#define ALPHABET_SIZE 'z' - 'a' + 1
#include <stdio.h>
int main(void)
{
printf("%d\n", 2*ALPHABET_SIZE);
printf("%d\n", ALPHABET_SIZE*2);
}
在我的 C 实现中,这会打印“148”和“27”。发生这种情况是因为,在第一个 printf
中,2*ALPHABET_SIZE
被替换为 2*'z' - 'a' + 1
,其被评估为 (2*'z') - 'a' + 1
,并且在第二个 printf
中,ALPHABET_SIZE*2
替换为 'z' - 'a' + 1*2
,计算结果为 'z' - 'a' + (1*2)
。由于这会产生两个不同的结果,因此证明使用 C 语义进行预处理不会用计算一次的单个表达式结果替换宏;它必须产生其他东西(实际上是一系列 预处理器标记 ),随后在上下文中重新解释。
我有这行代码:
#define ALPHABET_SIZE 'z' - 'a' + 1
当我将鼠标悬停在代码中的 ALPHABET_SIZE 上时,它告诉我它扩展到 'z' - 'a' + 1
。
所以我想知道是否每次在我的代码中使用 ALPHABET_SIZE 时都必须重新计算这个表达式?如果是这样,我怎样才能防止重新计算?
C 标准仅指定程序的可观察行为,而不是它们在幕后的工作方式。
是否每次都重新计算 'z' - 'a' + 1
不会影响可观察到的行为,因此由实现决定。
一般来说,您可以期待明智的编译器在 compile-time 处计算结果,尤其是在启用优化时。
#define ALPHABET_SIZE 'z' - 'a' + 1
pre-processor替换每个ALPHABET_SIZE
有
'z' - 'a' + 1
然后编译器很可能会执行 Constant folding 优化,用 26 替换计算。
Demo https://godbolt.org/z/Mo46db,表达式被26
替换为gcc 10.2
考虑以下程序:
#define ALPHABET_SIZE 'z' - 'a' + 1
#include <stdio.h>
int main(void)
{
printf("%d\n", 2*ALPHABET_SIZE);
printf("%d\n", ALPHABET_SIZE*2);
}
在我的 C 实现中,这会打印“148”和“27”。发生这种情况是因为,在第一个 printf
中,2*ALPHABET_SIZE
被替换为 2*'z' - 'a' + 1
,其被评估为 (2*'z') - 'a' + 1
,并且在第二个 printf
中,ALPHABET_SIZE*2
替换为 'z' - 'a' + 1*2
,计算结果为 'z' - 'a' + (1*2)
。由于这会产生两个不同的结果,因此证明使用 C 语义进行预处理不会用计算一次的单个表达式结果替换宏;它必须产生其他东西(实际上是一系列 预处理器标记 ),随后在上下文中重新解释。