这个问题是关于可变参数函数,以及它们的最后一个命名参数,在省略号之前:
void f(Type paramN, ...) {
va_list ap;
va_start(ap, paramN);
va_end(ap);
}
我正在阅读 C 标准,发现va_start
宏有以下限制:
参数 parmN 是函数定义中可变参数列表中最右边参数的标识符(就在 , ... 之前的那个)。如果参数 parmN 使用寄存器存储类、函数或数组类型或与应用默认参数提升后产生的类型不兼容的类型声明,则行为未定义。
我想知道为什么以下代码的行为未定义
void f(int paramN[], ...) {
va_list ap;
va_start(ap, paramN);
va_end(ap);
}
并且不是未定义的以下
void f(int *paramN, ...) {
va_list ap;
va_start(ap, paramN);
va_end(ap);
}
这些宏旨在通过纯 C 代码实现。但是纯 C 代码无法确定paramN
是声明为数组还是指针。在这两种情况下,参数的类型都被调整为指针。函数类型参数也是如此。
我想知道:这种限制的理由是什么?当这些参数调整在内部就位时,某些编译器是否在实现这一点时遇到问题?(同样的未定义行为也适用于 C++ - 所以我的问题也是关于 C++ 的)。