澄清在C函数指针 [英] Clarification on function pointers in C

查看:88
本文介绍了澄清在C函数指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下code来自例如 abo3.c从 不安全的编程 - 也见的为什么投的extern看跌一个函数指针(无效(*)(字符*))及看跌

  INT主(INT的argv,焦炭**的argc){
    EXTERN系统,看跌期权;
    无效(* FN)(字符*)=(无效(*)(字符*))及系统; //< ==
    焦炭BUF [256];
    FN =(无效(*)(字符*))及看跌期权;
    的strcpy(buf中,的argc [1]);
    FN(的argc [2]);
    出口(1);
}

特别是这一行:

 无效(* FN)(字符*)=(无效(*)(字符*))及系统;

我觉得无效(* FN)(字符*)听起来像是一个lambda,但我知道,这不是。
然后,也许这仅仅是带括号,其中无效* FN(字符*)是函数的声明一出戏,这功能是引用系统?但为什么在(字符* )的参数没有名字?这是允许的?


解决方案

 无效(* FN)(字符*)=(无效(*)(字符*))及系统;

这行采取了错误声明符号的地址系统(应 INT(为const char *) ,不隐 INT ),它施放到 FN 类型并初始化新的局部变量。结果
该类型是无效(*)(字符*)或函数指针接收一个的char * 和返回什么。


嗯,code是各种不良的:


  1. 前两个参数的传统命名为颠倒:

      INT主(INT的argv,焦炭**的argc)


  2. 声明系统看跌使用隐式int标准库函数为 INT 秒。这甚至不是错误的函数式,而是一种数据类型!

     的extern系统,提出;


  3. 铸造符号解决一个函数指针几乎是理智的。现在,只要它是正确的类型...无论如何,与数据指针和code三分球是同样大小的盒子,它的可能的不会丢失任何信息。

     无效(* FN)(字符*)=(无效(*)(字符*))及系统; //< ==
    FN =(无效(*)(字符*))及看跌期权;


  4. 检查是否的argv 至少2应该真正的的从略[!]:

     的strcpy(BUF,ARGC [1]);


  5. 通过调用错误类型的函数指针的函数为UB。不要那样做。此外,检查是否的argv [!]至少为3之前这一点的的可选的。
    FN(ARGC [2]);


  6. 这是隐式声明为依托的strcpy 退出也非常糟糕。无论是具有与一致的原型! (他们不返回 INT


The following code comes from example abo3.c from Insecure Programming — see also Why cast extern puts to a function pointer (void(*)(char*))&puts?:

int main(int argv,char **argc) {
    extern system,puts; 
    void (*fn)(char*)=(void(*)(char*))&system; // <==
    char buf[256];
    fn=(void(*)(char*))&puts;
    strcpy(buf,argc[1]);
    fn(argc[2]);
    exit(1);
}

Specifically this line:

void (*fn)(char*)=(void(*)(char*))&system;

I think that void (*fn)(char*) sounds like a lambda, but I know that it's not. Then, maybe this is only a play with parentheses, where void *fn(char*) is a declaration of a function and this function is referencing system? But why does the (char*) parameter have no name? Is this permitted?

解决方案

void (*fn)(char*)=(void(*)(char*))&system;

That line takes the address of the mis-declared symbol system (should be int(const char*), not implicit int), casts it to the type of fn and initializes that new local variable.
The type is void(*)(char*) or pointer to function receiving a single char* and returning nothing.


Well, that code is all kinds of bad:

  1. The traditional naming of the first two arguments to main is reversed:

    int main(int argv,char **argc)
    

  2. Declaring the standard-library-functions system and puts using "implicit int" as ints. That's not even the wrong function-type, but a data-type!

    extern system,puts;
    

  3. Casting the symbols address to a function-pointer is nearly sane. Now if only it was the right type... Anyway, on a box with data-pointers and code-pointers being the same size, it probably doesn't loose any information.

    void (*fn)(char*)=(void(*)(char*))&system; // <==
    fn=(void(*)(char*))&puts;
    

  4. Checking whether argv [!] is at least 2 should really not be omitted here:

    strcpy(buf,argc[1]);
    

  5. Calling a function through a function-pointer of wrong type is UB. Don't do that. Also, checking whether argv[!] is at least 3 before this point is not optional. fn(argc[2]);

  6. Relying on implicit declaration for strcpy and exit is also really bad. Neither has a prototype consistent with that! (they don't return int)

这篇关于澄清在C函数指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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