这是一个通用的函数指针和它是危险的? [英] Is this a generic function pointer and is it dangerous?

查看:150
本文介绍了这是一个通用的函数指针和它是危险的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

学习和函数指针搞乱了,我发现一个方法来初始化空函数指针和扮演他们。然而,尽管我没有收到任何警告或错误,无论是与海湾合作委员会或VS的编译器,我想知道它是否是危险的或坏的做法,这样做,因为我没有看到的往往初始化函数指针的这种方式互联网。此外,我们称这种通用的函数指针?

的#include<&stdio.h中GT;
#包括LT&;&stdint.h GT;
#包括LT&;&CONIO.H GT;的#define PAUSE(_getch())uint16_t添加(常量uint16_t X,常量uint16_t Y){
    返回X + Y;
}字符CHR(uint8_t有测试){
    返回(焦炭)的测试;
}诠释主要(无效){    无效(*测试)()=(无效*)增加;    常量uint16_t X = 1,Y = 1;
    uint16_t值=((uint16_t(*)())测试)(X,Y);    测试=(无效*)CHR;    的printf(%d个\\ N,加(X,Y)); // 2
    的printf(%d个\\ N,值); // 2
    的printf(%C \\ n,((CHAR(*)())测试)(100)); //ð    暂停;
    返回0;
}


解决方案

  

这是一个通用的函数指针


没有,如果我没有弄错得要命,有没有这样的东西在C通用函数指针。


  

和是不是很危险吗?


是的,是的。它是邪恶的。


有几个你需要知道的东西。首先,除非你正在运行符合POSIX系统,

 无效(*测试)()=(无效*)增加;

错误的。 无效* 是一个指针,用于─ 对象类型的,因此,它不与函数指针兼容。 (至少在标准C - 正如我所说,POSIX要求它与函数指针也兼容)

第二件事是,无效(* FP)()无效(* FP)(无效)是不同的。前者报关证 FP 采取任何数量的任何类型的参数,参数的数量和类型将被推断编译器看到第一次调用函数时(指针)。

另一个重要的方面是,函数指针保证在相互转换(据我所知这体现在具有相同重presentation和对齐要求它们)。这意味着任何函数指针可以被分配到(地址)的功能(一个合适的投后),只要你不拨打通过指针为不兼容的类型的函数。该行为被明确定义,当且仅当你调用它之前转换指针回到原来的类型。

所以,如果你想要一个通用的函数指针,你可以写类似

 无效的typedef(* fn_ptr)(无效);

然后你可以指定任何函数指针类型为 fn_ptr 的对象。你有什么要注意的是,再次转化为正确的类型调用函数时,如:

 添加INT(INT A,INT B);fn_ptr FP =(fn_ptr)增加;法律//
FP(); // WRONG!
INT X =((INT(*)(INT,INT))FP)(1,2); //好

Learning and messing up with function pointers, I noticed a way to initialize void function pointers and cast them. Yet, although I don‘t receive any warning or error, either with GCC or VS’s compiler, I wanted to know whether it was dangerous or a bad practice to do this as I don't see this way of initializing function pointers often on the Internet. Moreover, do we call this generic function pointer?

#include <stdio.h>
#include <stdint.h>
#include <conio.h>

#define PAUSE (_getch())

uint16_t add(const uint16_t x, const uint16_t y) {
    return x + y;
}

char chr(uint8_t test) {
    return (char)test;
}

int main(void) {

    void(*test)() = (void*)add;

    const uint16_t x = 1, y = 1;
    uint16_t value = ((uint16_t(*)())test)(x, y);

    test = (void*)chr;

    printf("%d\n", add(x, y));                    // 2
    printf("%d\n", value);                        // 2
    printf("%c\n", ((char(*)())test)(100));       // d

    PAUSE;
    return 0;
}

解决方案

Is this a generic function pointer

No, if I'm not terribly mistaken, there's no such thing as a "generic function pointer" in C.

and is it dangerous?

Yes, it is. It is evil.


There are a couple of things you need to know. First, unless you are running a system that conforms to POSIX,

void(*test)() = (void*)add;

is wrong. void * is a pointer-to-object type, and as such, it is not compatible with function pointers. (At least not in standard C -- as I mentioned, POSIX requires it to be compatible with function pointers too.)

The second thing is that void (*fp)() and void (*fp)(void) are different. The former declaration permits fp to take any number of parameters of any type, and the number of arguments and their types will be inferred when the compiler sees the first call to the function (pointer).

Another important aspect is that function pointers are guaranteed to be convertible across each other (AFAIK this manifests in them having the same representation and alignment requirements). This means that any function pointer can be assigned to (the address of) any function (after an appropriate cast), so long as you do not call a function through a pointer to an incompatible type. The behavior is well-defined if and only if you cast the pointer back to the original type before calling it.

So, if you want a "generic" function pointer, you can just write something like

typedef void (*fn_ptr)(void);

and then you could assign any pointer to function to an object of type fn_ptr. What you have to pay attention to is, again, the conversion to the right type when invoking the function, as in:

int add(int a, int b);

fn_ptr fp = (fn_ptr)add; // legal
fp(); // WRONG!
int x = ((int (*)(int, int))fp)(1, 2); // good

这篇关于这是一个通用的函数指针和它是危险的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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