为什么取消定义宏在达到#undef 之前生效?

Why un-defining a macro takes effect before #undef is reached?

#include <stdio.h>

void f(void);

#define N 100

int main(void)
{
    f();
#ifdef N
#undef N
#endif

    return 0;
}

void f(void){
#if defined(N)
  printf("N is %d\n",N);
#else
  printf("N is undefined\n");
#endif // defined
}

抱歉,问题和之前一样,但略有不同。这里写的相同代码 N 未定义

#include <stdio.h>

void f(void);

#define N 100

int main(void)
{
#if defined(N)
  printf("N is %d\n",N);
#else
  printf("N is undefined\n");
#endif // defined
/**f();
#ifdef N
#undef N
#endif**/

return 0;
}

/**void f(void){
}**/

但是,如果我在 main 中编写 f 函数的定义,它会打印输出 N is 100。为什么会出现这种打印以及为什么会有所不同?

你必须在脑海中分开两条时间线:

  • 编译时间轴 - 即编译程序时发生的事情,以及
  • 运行 时间轴 - 即程序运行时发生的事情

这两条时间线是相互独立的。编译时间线大致对应于程序的文本顺序,对 #include 处理和宏扩展进行了一些更正。 运行 时间线由程序的控制结构、函数调用等决定。

由于这两个时间线是独立的,因此在编译时间线期间到达之前点Y的代码中的X点很可能在之后 运行 时间线中的 Y 点。此外,它可能会多次到达 - 在另一个点 Y 之前和之后。

现在让我们回到你的问题。 #defines和宏在编译时展开,所以beforeafter是专指到编译时间表。当您将 #undef 放在 main 中时,在您的函数 f 上方,未定义发生 使用 N 之前,导致到编译时错误。 运行 时间线,据此 f 的调用发生在 之前 未定义没有相关性,因为 #defines 是一个排他性编译-时间构造。