仅当使用vararg省略号时,函数指针“从不兼容的指针类型赋值”

时间:2013-12-19 00:37:23

标签: c function-pointers variadic-functions c11

我知道声明一个没有参数列表的函数(或函数指针)(并且在参数列表中没有指定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问题几乎同样问题。答案都在“它不能那样工作”的范围内,没有明确提到标准,为什么它不会那样工作。


  • 为什么编译器会生成警告?
  • 这种行为(警告旁边)是否可靠?
  • 这种行为编译器是否具体(阅读另一个问题,看来mingw x86_64在2011年不支持它)?
  • 此行为平台是否具体?

1 个答案:

答案 0 :(得分:1)

见C标准的6.7.5.3:

  

此外,参数类型列表(如果两者都存在)应该同意   参数的数量和省略号终止符的使用;   相应的参数应具有兼容的类型。如果有一种类型   参数类型列表,另一种类型由函数指定   不属于函数定义且包含的声明符   一个空的标识符列表,参数列表不应该有   省略号终止符和每个参数的类型应该是兼容的   使用默认应用程序产生的类型   争论促销。

这表示将varargs函数赋值给fp的类型不兼容。

此外,正如我在上面的评论中所指出的,该程序具有未定义的行为,根据定义它是不可靠的......它可能在一个平台上的一个实现的一个版本中起作用,但在其他版本,实现和平台中失败。 ..它甚至可能工作一天但不是下一个,或者在程序的一个部分而不是另一个部分。实际上,在某些实现中,varargs和非varargs函数的调用序列是不同的,并且当在这样的实现上运行时,您的程序可能会崩溃。