Chr*_*eux 3 c casting function-pointers
据我所知,在不兼容的函数指针之间进行转换,例如:
void aUnaryFunction(int a1)
{
/* .... */
}
void doSomethingWithFn()
{
typedef void(*BinaryFn)(int, const char*);
BinaryFn aBinaryFunction = (BinaryFn) &aUnaryFunction;
aBinaryFunction (3, "!!!");
}
Run Code Online (Sandbox Code Playgroud)
永远不应该这样做,因为根据C标准,"未定义的行为".
但是我不明白为什么,假设函数调用在C中工作的方式,这个例子是不安全的.我所做的只是无视一个论点.
假设int第一个参数的处理是一致的,所有会发生的是const char*将在doSomethingWithFn()调用时放入寄存器中aBinaryFunction,aUnaryFunction将按预期运行,并且const char*可能会被覆盖aUnaryFunction,但这很好,因为无论如何,别的什么都不会用.
我在这里遗漏了什么,或者这实际上是安全的吗?(或两者之间,或两者兼而有之?)
问题是没有一个"方式函数调用C语言工作" - 只有函数调用在特定C实现上工作的方式.
作为一个具体的例子,"被调用者清理"调用约定(如x86 stdcall)要求被调用者知道有多少参数被推送到堆栈以执行正确的清理,这将在您的示例中被破坏.
这归结为呼叫约定.如果参数以相反的顺序"发送",例如怎么办?或者,如果在依赖正确数量的参数的函数调用之后必须执行标准过程?
您的建议可能有用,但您不应该依赖于此,并且标准将此属性定义为未定义的行为.