【发布时间】:2023-03-30 07:15:01
【问题描述】:
此代码是否会导致明确定义的行为?如果不是,那么违反了 C 标准的哪些规则/声明?它们究竟是如何被违反的?
代码 #1:
#define B(a1, ...) a1
int main ( void )
{
return B(0);
}
代码 #2:
#define M1(...) M2(0
#define M2(a) a
int main ( void )
{
return M1(0));
}
【问题讨论】:
-
@UnslanderMonica,预处理器标准中的大多数“应”确实出现在约束部分,因此违反它们需要诊断。但并非所有都是这种情况,这里给出的第一个例子确实没有定义行为。
-
@JensGustedt 很好。这些是恕我直言,标准中的技术缺陷 - 没有必要对此未定义...... :(
-
@UnslanderMonica,我不这么认为。 UB 在 C 标准中有不同的原因。其中之一是让实现松懈以提供自己的定义,预处理器中的此类 UB 可能就是这种情况。
-
@JensGustedt 为实现提供“松弛”通常会使该功能无用,因为您不能依赖可移植代码中的任何特定行为。但是我学到了一些新东西——我没有意识到这种基本的预处理器行为是未定义的。它可能至少是实现定义的,这通常意味着实现者至少会费心记录他们放入的行为。由于预处理器中未定义的行为,大多数实现甚至都不会费心记录它,所以你不能依赖它在下一个版本中不会改变,别介意在另一个编译器上......
-
@UnslanderMonica:关于“没用,因为您不能依赖可移植代码中的任何特定行为”:所以?并非每个人的目标都是创建通用可移植的代码。 C 的一个基本特征是它被设计为灵活的,因此它可以在许多平台上提供编程语言,并且在这方面取得了巨大的成功。不再需要每个人都必须在新处理器上学习汇编,或者制造商必须繁琐地构建一些新的编译器;有一个可以移植的通用编程基础……
标签: c c-preprocessor undefined-behavior c11