看一下下面的例子:
#include <iostream>
#include <string.h>
void Func1(int x)
{
std::cout << "I'm function 1: " << x << std::endl;
}
void Func2(int x, const char* str)
{
std::cout << "I'm function 2: (this is arg1: " << x << " - args2: " << str << ")" << std::endl;
}
uintptr_t GetProcAddress(const char* _str)
{
if (strcmp(_str, "func1") == 0)
{
return reinterpret_cast<uintptr_t>(Func1);
}
else
{
return reinterpret_cast<uintptr_t>(Func2);
}
}
int main()
{
typedef void(*PROCADDR)(int, const char*);
PROCADDR ext_addr = nullptr;
ext_addr = (PROCADDR)GetProcAddress((const char*)"func1");
//call the function
ext_addr(10, "arg");
std::cin.get();
return 0;
}
我们基本上用2个参数调用Func1,并且可以切换到使用相同的args调用Func2,一切都按预期工作。
当然,两个参数的地址总是被推送到堆栈,即使第二个参数从未被函数本身使用过。
现在我明白上面的代码永远不应该用在生产代码中,但我的主要问题是,上面的代码能否导致UB,或者代码总是希望这样做?
祝你好运 XX
答案 0 :(得分:1)
是的,这是未定义的行为。来自[expr.reinterpret.cast]:
函数指针可以显式转换为不同类型的函数指针。打电话的效果 函数类型(8.3.5)的函数与函数定义中使用的类型不同是未定义的。