如果我投一个函数指针,改变参数的数量会发生什么 [英] What happens if I cast a function pointer, changing the number of parameters

查看:114
本文介绍了如果我投一个函数指针,改变参数的数量会发生什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始我的包裹在四周C.函数指针头要了解的函数指针铸造的作品怎么样,我写了下面的程序。它基本上创建了一个函数指针,有一个参数,它与三个参数强制转换为一个函数指针,并调用函数,提供三个参数的函数。我很好奇,会发生什么:

I'm just beginning to wrap my head around function pointers in C. To understand how casting of function pointers works, I wrote the following program. It basically creates a function pointer to a function that takes one parameter, casts it to a function pointer with three parameters, and calls the function, supplying three parameters. I was curious what would happen:

#include <stdio.h>

int square(int val){
  return val*val;
}

void printit(void* ptr){
  int (*fptr)(int,int,int) = (int (*)(int,int,int)) (ptr);
  printf("Call function with parameters 2,4,8.\n");
  printf("Result: %d\n", fptr(2,4,8));
}


int main(void)
{
    printit(square);
    return 0;
}

这编译并没有错误或警告(在Linux / x86平台的gcc -Wall)运行。我的系统上的输出是:

This compiles and runs without errors or warnings (gcc -Wall on Linux / x86). The output on my system is:

Call function with parameters 2,4,8.
Result: 4

所以显然是多余的参数被简单地丢弃。

So apparently the superfluous arguments are simply silently discarded.

现在我想明白了什么是真正发生在这里。

Now I'd like to understand what is really happening here.


  1. 至于合法性:如果我理解的答案,<一个href=\"http://stackoverflow.com/questions/559581/casting-a-function-pointer-to-another-type\">http://stackoverflow.com/questions/559581/casting-a-function-pointer-to-another-type正确的,这简直是不确定的行为。所以,这种运行并且产生一个合理的结果其实就是纯粹是运气,是否正确? (或正派的编译器编写者的一部分)

  2. 为什么不GCC提醒我这一点,甚至与华尔街?这是不是编译器只是不能检测?为什么呢?

  1. As to legality: If I understand the answer to http://stackoverflow.com/questions/559581/casting-a-function-pointer-to-another-type correctly, this is simply undefined behaviour. So the fact that this runs and produces a reasonable result is just pure luck, correct? (or niceness on the part of the compiler writers)
  2. Why will gcc not warn me of this, even with Wall? Is this something the compiler just cannot detect? Why?

我是从Java,其中类型检查是有很多严格的到来,所以这种行为弄得我有点。也许我经历了文化冲击: - )

I'm coming from Java, where typechecking is a lot stricter, so this behaviour confused me a bit. Maybe I'm experiencing a cultural shock :-).

推荐答案

额外的参数不会被丢弃。他们得到妥善安置在堆栈上,仿佛调用到需要三个参数的函数进行。然而,由于你的函数只关心一个参数,它看起来只是在堆栈的顶部,不接触其他参数。

The extra parameters are not discarded. They are properly placed on the stack, as if the call is made to a function that expects three parameters. However, since your function cares about one parameter only, it looks only at the top of the stack and does not touch the other parameters.

这个调用工作的事实是纯粹是运气,立足于两个事实:

The fact that this call worked is pure luck, based on the two facts:


  • 第一参数的类型是用于功能和铸造指针相同。如果你改变了功能,用一个指针指向字符串,并尝试打印字符串,你会得到一个不错的崩溃,因为code将尝试取消引用指针来解决内存2。

  • 在默认情况下使用的调用约定是调用者清理堆栈。如果更改调用约定,使得被叫方清理堆栈,则最终将与呼叫方推栈上三个参数,然后被叫清理(或相当企图)一个参数。这可能会导致堆栈损坏。

有没有办法编译器可以警告你一个简单的原因这样的潜在的问题 - 在一般情况下,它不知道指针在编译时的价值,所以不能评价一下它指向。试想一下,函数指针指向在运行时创建一个类虚拟表的方法?所以,你告诉编译器它是一个指向有三个参数的函数,编译器会相信你。

There is no way the compiler can warn you about potential problems like this for one simple reason - in the general case, it does not know the value of the pointer at compile time, so it can't evaluate what it points to. Imagine that the function pointer points to a method in a class virtual table that is created at runtime? So, it you tell the compiler it is a pointer to a function with three parameters, the compiler will believe you.

这篇关于如果我投一个函数指针,改变参数的数量会发生什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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