c++:将指针转换为函数安全吗?

发布于 2024-12-22 23:07:16 字数 464 浏览 6 评论 0原文

我想知道将 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

往日情怀 2024-12-29 23:07:16

您不能直接将 double(*)(double) 分配给 double(*)(...),但您可以reinterpret_cast 它。 §5.2.10[expr.reinterpret.cast]/6 明确允许强制转换,但调用强制转换的函数指针将导致未定义的行为:

函数指针可以显式转换为不同类型的函数指针。

通过指向与函数定义中使用的类型不同的函数类型的指针来调用函数的效果是未定义

除了将“指向 T1 的指针”类型的纯右值转换为“指向 T2 的指针”类型(其中 T1T2 是函数类型)并返回到其原始类型产生原始指针值,这种指针转换的结果是未指定的。

很容易理解为什么它会导致 UB — 如果我们调用 generalized(1.0, 2.0, 3.0) 会怎样?这可能会损坏调用堆栈。但是,如果您在调用之前将 generalized 转换回 double(*)(double) ,那就没问题了。

You cannot directly assign a double(*)(double) to double(*)(...), but you could reinterpret_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:

A function pointer can be explicitly converted to a function pointer of a different type.

The effect of calling a function through a pointer to a function type that is not the same as the type used in the definition of the function is undefined.

Except that converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are function types) and back to its original type yields the original pointer value, the result of such a pointer conversion is unspecified.

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 the generalized back to a double(*)(double) before you call it.

是的,铸造本身是允许的。但是,用错误的签名来调用它则不然。请注意,如果您想要通用函数指针,最好使用 void (*)(),它类似于函数指针的 void*(不过,没有隐式转换)。

或者甚至更好,因为您显然提供了特定的参数,所以使用 std::functionstd::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 like void* for function pointers (no implicit conversion to it, though).

Or even better, since you apperently provide specific arguments, use std::function and std::bind (if your compiler supports C++11 libraries), or their Boost equivalents.

机场等船 2024-12-29 23:07:16

使 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文