7

可能重复:
将函数指针转换为另一种类型

假设我用一个实际上需要比函数指针定义更少的参数的函数初始化一个函数指针,如果通过函数指针调用该函数是否仍能正确执行?

我用 gcc 进行了尝试,它按预期工作,但我想知道这种行为在编译器/平台之间是否一致(我怀疑在某些环境中它可能会对堆栈造成严重破坏):

#include <stdio.h>

typedef void (*myfun)(int, int, int);

void test_a(int x, int y, int z) {
    printf("test_a %d %d %d\n", x, y, z);
}

void test_b(int x, int y) {
    printf("test_b %d %d\n", x, y);
}

int main() {
    myfun fp;
    fp = test_a;
    fp(1, 2, 3);
    fp = (myfun) test_b;
    fp(4, 5, 6);
}
4

4 回答 4

12

这是未定义的行为。使用风险自负。传闻会引起鼻魔!

在此处输入图像描述

于 2012-11-18T21:27:10.807 回答
5

您的程序的行为是未定义的。它完全编译的事实是因为强制转换,它有效地告诉编译器“这是错误的,但无论如何都要这样做”。如果您删除演员表,您将收到相应的错误消息:

a.c:17:8: error: assignment from incompatible pointer type [-Werror]

(从gcc -Wall -Werror。)

更具体地说,行为取决于调用约定。如果您在一个平台上,参数在堆栈上以“反向”顺序传递,程序将给出非常不同的结果。

于 2012-11-18T21:25:19.097 回答
3

函数调用是未定义的行为。

(C99,6.3.2.3p8)“[...] 如果转换后的指针用于调用类型与指向的类型不兼容的函数,则行为未定义。”

有关信息,请注意函数类型

(C99,6.2.5p20)“[...] 描述了具有指定返回类型的函数。函数类型的特征在于其返回类型以及其参数的数量和类型。”

于 2012-11-18T21:29:14.393 回答
2

它是否有效取决于所使用的调用约定

我不会推荐它。

于 2012-11-18T21:28:59.587 回答