调用一个函数指针,其分配的功能少的参数则指针类型 [英] Calling a function pointer whose assigned function has less arguments then the pointer type

查看:128
本文介绍了调用一个函数指针,其分配的功能少的参数则指针类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下code:

#include <iostream>

typedef int (*test_func_t) (int, int, int);

int print_integer (int a)
{
    std::cout << "num: " << a << "\n";
    return a;
}

int main (int argc, char * argv[])
{
    test_func_t func = (test_func_t) &print_integer;
    std::cout << "calling with 3 parameters func(5,7,9)\n";
    func(5,7,9);
    return 0;
}

正如你所看到的,一个类型(test_func_t)被定义为3 INT参数的函数。一个函数指针(FUNC)分配的指针print_integer,即只接收1个参数,函数指针,然后用3个参数被称为(5,7,9)。

As you can see, a type (test_func_t) is defined as a function with 3 int arguments. A function pointer (func) is assigned with a pointer to "print_integer", which receives only 1 argument, and the function pointer is then called with 3 arguments (5, 7, 9).

这code ++工程,并产生NUM:5。输出

This code works and produces "num: 5" output.

GDB disas输出(Intel语法)

gdb disas output (Intel syntax)

disas main
...
   0x080486cb <+9>:     mov    DWORD PTR [esp+0x1c],0x804867d
...
   0x080486e0 <+37>:    mov    DWORD PTR [esp+0x8],0x9
   0x080486e8 <+45>:    mov    DWORD PTR [esp+0x4],0x7
   0x080486f0 <+53>:    mov    DWORD PTR [esp],0x5
   0x080486f7 <+60>:    mov    eax,DWORD PTR [esp+0x1c]
   0x080486fb <+64>:    call   eax

disas print_integer
   ...
   0x08048683 <+6>:     mov    DWORD PTR [esp+0x4],0x8048830
   0x0804868b <+14>:    mov    DWORD PTR [esp],0x8049ae0
   0x08048692 <+21>:    call   0x8048530 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)@plt>
   0x08048697 <+26>:    mov    edx,DWORD PTR [ebp+0x8]
   0x0804869a <+29>:    mov    DWORD PTR [esp+0x4],edx
   0x0804869e <+33>:    mov    DWORD PTR [esp],eax
   0x080486a1 <+36>:    call   0x80484d0 <std::ostream::operator<<(int)@plt>

正如你所看到的,剩余参数([EBP + 0×12]和[EBP + 0x16])根本不使用。

As you can see, the rest of the arguments ([ebp+0x12] and [ebp+0x16]) are simply not used.

我的问题:


  1. 这似乎与__cdecl调用约定在Linux x86工作。它是安全的其他架构和调用约定呢?

  2. 是否有C / C ++标准允许/定义从预期更少的参数的函数分配一个函数指针的结果?

这样的实例:node.js的的 NODE_MODULE 注册的键入一个函数有3个参数[出口,模块,私法。这是称为与3 但正式的例子显示使用功能1 或的 2 参数。

Example of such use: node.js's NODE_MODULE registers a function whose type has 3 arguments [exports, module, priv]. It is called with those 3 but formal examples show registering of a function with 1 or 2 arguments.

推荐答案

这引述C ++ 11标准的 expr.reinter pret.cast 6 :​​

Quoting from the C++11 standard expr.reinterpret.cast 6:

一个函数指针可以显式转换为另一种类型的一个函数指针。打电话的影响
  通过指针函数类型(8.3.5)的功能是不一样的定义中使用的类型
  的功能的未定义

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 (8.3.5) that is not the same as the type used in the definition of the function is undefined.

所以,我要说,这是的不可以一般是安全的。这是未定义的行为。这就是说,我不知道如何执行其他C在这种情况下++行为。

So, I'd say that it is not safe in general. It is undefined behaviour. That said, I don't know how other implementation of C++ behave in this situation.

这篇关于调用一个函数指针,其分配的功能少的参数则指针类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆