我知道声明一个没有参数列表的函数(或函数指针)(并且在参数列表中没有指定void
)这意味着函数(或函数指针)具有未知数量的参数。< / p>
我写了一些测试脚本来检查这种行为:
int my_func_1() {
return(0);
}
int my_func_2(int x) {
return(x);
}
int my_func_3(char x, ...) {
va_list va;
va_start(va, x);
return(va_arg(va, int));
}
int (*fp)();
fp = my_func_1;
printf("%d\n", fp());
fp = my_func_2;
printf("%d\n", fp(33));
fp = my_func_3;
printf("%d\n", fp(33, 44));
我在linux下的64位机器上编译了这个:
gcc test.c -Wextra -pedantic -std=c1x -O3 -o test
输出正确:
0
33
44
但是我收到了这个警告:assignment from incompatible pointer type
。为什么在使用vararg省略号时才显示此警告?
由于指针类型被认为是不完整的,因此指定完整类型不应构成“从不兼容的指针类型分配”。此外,只要vararg省略号不存在,分配完整类型就可以不带任何警告
这个other问题几乎同样问题。答案都在“它不能那样工作”的范围内,没有明确提到标准,为什么它不会那样工作。
答案 0 :(得分:1)
见C标准的6.7.5.3:
此外,参数类型列表(如果两者都存在)应该同意 参数的数量和省略号终止符的使用; 相应的参数应具有兼容的类型。如果有一种类型 参数类型列表,另一种类型由函数指定 不属于函数定义且包含的声明符 一个空的标识符列表,参数列表不应该有 省略号终止符和每个参数的类型应该是兼容的 使用默认应用程序产生的类型 争论促销。
这表示将varargs函数赋值给fp的类型不兼容。
此外,正如我在上面的评论中所指出的,该程序具有未定义的行为,根据定义它是不可靠的......它可能在一个平台上的一个实现的一个版本中起作用,但在其他版本,实现和平台中失败。 ..它甚至可能工作一天但不是下一个,或者在程序的一个部分而不是另一个部分。实际上,在某些实现中,varargs和非varargs函数的调用序列是不同的,并且当在这样的实现上运行时,您的程序可能会崩溃。