c++:将指针转换为函数安全吗?
我想知道将 double (*)(double)
转换为 double(*)(...)
是否安全,这将用于泛化可能具有指向多个函数的指针的代码。
到目前为止,我已经将要传递给函数的所有内容存储在向量中,我想知道是否有一种方法可以在通用代码中调用函数(同时传递正确数量的参数)?我的意思是这样的:
//while initializing
mFunction = sin;
//later in code
double (*generalized)(...) = mFunction;
for(i=0;i<args.size();i++)
pusharg(args[i]);
call(generalized);
--edit--
如果没有有效的方法使用 c++ 来执行此操作,是否可以使用程序集安全地调用该函数?
I'm wondering if it's safe to cast a double (*)(double)
to double(*)(...)
, this is going to be used to generalize a code which may have pointers to multiple functions.
so far I've stored every thing that is going to be passed to the function in a vector, and I'm wondering if there is a way to call a function (while passing the correct number of arguments) in a generalized code? I mean something this:
//while initializing
mFunction = sin;
//later in code
double (*generalized)(...) = mFunction;
for(i=0;i<args.size();i++)
pusharg(args[i]);
call(generalized);
--edit--
if there is not a valid way to do it using c++ is it possible to saftly call the function using assembly?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您不能直接将
double(*)(double)
分配给double(*)(...)
,但您可以reinterpret_cast
它。 §5.2.10[expr.reinterpret.cast]/6 明确允许强制转换,但调用强制转换的函数指针将导致未定义的行为:很容易理解为什么它会导致 UB — 如果我们调用
generalized(1.0, 2.0, 3.0)
会怎样?这可能会损坏调用堆栈。但是,如果您在调用之前将generalized
转换回double(*)(double)
,那就没问题了。You cannot directly assign a
double(*)(double)
todouble(*)(...)
, but you couldreinterpret_cast
it. The cast is explicitly allowed by §5.2.10[expr.reinterpret.cast]/6, but calling the casted function pointer will cause undefined behavior:It is easy to see why it leads to UB — what if we call
generalized(1.0, 2.0, 3.0)
? This will likely corrupt the call stack. But it is fine if you cast thegeneralized
back to adouble(*)(double)
before you call it.是的,铸造本身是允许的。但是,用错误的签名来调用它则不然。请注意,如果您想要通用函数指针,最好使用
void (*)()
,它类似于函数指针的void*
(不过,没有隐式转换)。或者甚至更好,因为您显然提供了特定的参数,所以使用
std::function
和std::bind
(如果您的编译器支持 C++11 库)或其 Boost等价物。Yes, the casting itself is allowed. To call it with a wrong signature is not, though. Note that if you want a generic function pointer, better use
void (*)()
, it's likevoid*
for function pointers (no implicit conversion to it, though).Or even better, since you apperently provide specific arguments, use
std::function
andstd::bind
(if your compiler supports C++11 libraries), or their Boost equivalents.使
generalized
变得易失性将要求编译器遵循 ABI 规范。由于希望支持未声明的 C 函数,如果不通过具有固定数量参数的指向函数的指针来调用除可变数量参数之外的函数,那么这在大多数 ABI(包括 x86 和 x86-32)上是安全的。Making
generalized
volatile will require the compiler to follow the ABI specification. Due to a desire to support non-declared C functions this is safe on most ABIs (including x86 and x86-32) if one does not call a function that excepts a variable number of arguments though a pointer to function with a fixed number of arguments.