这是一个通用函数指针吗?它危险吗?

2024-01-01

在学习和搞乱函数指针时,我注意到一种初始化 void 函数指针并强制转换它们的方法。然而,虽然我没有收到任何警告或错误,无论是使用 GCC 还是 VS 的编译器,我想知道这样做是否危险或不好的做法,因为我经常在网上看到这种初始化函数指针的方法。互联网。此外,我们称这个通用函数指针吗?

#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;
}

这是一个通用函数指针吗

不,如果我没有弄错的话,C 中不存在“通用函数指针”这样的东西。

这危险吗?

是的。这是邪恶的。


您需要了解一些事情。首先,除非你运行的是符合 POSIX 的系统,

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

is wrong. void *是一个指针object类型,因此它与函数指针不兼容。 (至少在标准 C 中不是这样——正如我提到的,POSIX 也要求它与函数指针兼容。)

第二件事是void (*fp)() and void (*fp)(void)是不同的。以前的声明允许fp接受任意数量、任意类型的参数,当编译器看到第一次调用函数(指针)时,将推断出参数的数量及其类型。

另一个重要的方面是保证函数指针可以相互转换(据我所知,这表明它们具有相同的表示和对齐要求)。这意味着任何函数指针都可以分配给任何函数(在适当的强制转换之后)(的地址),只要您不这样做call通过指向不兼容类型的指针的函数。当且仅当在调用指针之前将指针强制转换回原始类型时,该行为才是明确定义的。

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

typedef void (*fn_ptr)(void);

然后你可以将任何指向函数的指针分配给类型的对象fn_ptr。同样需要注意的是,调用函数时要转换为正确的类型,如下所示:

int add(int a, int b);

fn_ptr fp = (fn_ptr)add; // legal
fp(); // WRONG!
int x = ((int (*)(int, int))fp)(1, 2); // good
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

这是一个通用函数指针吗?它危险吗? 的相关文章

随机推荐

  • 在公共功能分支中使用 git rebase

    您可以在网上看到人们建议不要使用git rebase在公共分支中 但如果您总是对功能分支进行变基 我看不出问题是什么 我的团队总是使用分支来实现功能 哇 我们习惯于在本地拥有它 所以变基不是问题 但有时我们想向其他开发人员展示部分完成的功能
  • 在nodeJs中,有没有一种方法可以在不使用数组大小​​的情况下循环数组?

    假设我有 myArray item1 item2 I tried for var item in myArray console log item 它打印 0 1 我所希望的是拥有 项目1 项目2 是否有任何其他语法可以在不使用的情况下工作
  • 如何在php中获取选定表项的id

    我应该得到id从表中提出请求 但我就是这样做的 我的桌子 id AI 名称 Varchar authir varchar 类别 varchar 我想如果有任何解决方案可以解决这个问题 谢谢我的问题出现在以下几行中 Print td a hr
  • Java Collection 的多个索引 - 最基本的解决方案?

    我正在寻找在 Java 集合上创建多个索引的最基本的解决方案 所需功能 当删除某个值时 与该值关联的所有索引条目都必须删除 索引查找必须比线性搜索更快 至少与 TreeMap 一样快 附带条件 不依赖于大型 如 Lucene 库 没有不常见
  • JSDOM:无法解析 CSS 样式表

    使用以下命令 node modules babel core register js node modules jsdom global register js spec jsx 我正在运行以下测试文件 use strict import
  • 导入后完整日历样式不正确

    我正在尝试在我的项目中使用 React Full Calendar 尽管日历以正确的方式呈现 但样式有点不对劲 目前的情况如下 正如您所看到的 在标题工具栏中 月份单词没有在中间对齐 其他单词和图标也是如此 也许 按钮本身的尺寸在高度上看起
  • 如何使用/安装 python 2to3?

    由此https docs python org 3 4 library 2to3 html https docs python org 3 4 library 2to3 html它说 2to3 应该作为脚本与 python 解释器一起安装
  • 如何告诉 RandomizedSearchCV 选择分布或 None 值?

    假设我们正在努力寻找最好的max depth的参数RandomForestClassifier http scikit learn org stable modules generated sklearn ensemble RandomFo
  • ddply 按 R 中的组求和

    我有一个示例数据框 数据 如下所示 X Y Month Year income 2281205 228120 3 2011 1000 2281212 228121 9 2010 1100 2281213 228121 12 2010 900
  • std::setw 和 unicode 字符

    我的问题如以下最小示例所示 include
  • 如何向此 CSS“切换器”“切换开关”添加文本

    这是实际的 Switcher 生成器 https proto io freebies onoff https proto io freebies onoff 我不清楚如何向事件添加文本 因此 当开关处于默认状态时 会显示某些文本 反之亦然
  • Mathematica 绘图中多个函数的检测和样式设置

    This https stackoverflow com questions 5597566 这个问题让我开始思考 Mathematica 如何检测正在绘制的多个函数 我发现我实在是看不懂这个流程 考虑 Plot 1 Sequence 2
  • 如何为二维数组的 qsort 编写比较器函数?

    我有一个 n 2 大小的数组 我想根据第二列的值使用 qsort 对它们进行排序 include
  • IEquatable,如何正确实施[重复]

    这个问题在这里已经有答案了 我正在使用 net 2 0 和 c 并且我已经在我的类中实现了 IEquatible 接口 如下所示 public MyClass IEquatable
  • 如何计算 char 数组中的元素数量?

    我试图计算数组中的元素数量 并被告知该行 int r sizeof array sizeof array 0 会给我数组中元素的数量 我发现该方法确实有效 至少对于 int 数组而言 然而 当我尝试这段代码时 事情就崩溃了 include
  • 为 Galaxy S8 创建模拟器? - 安卓工作室

    我创建了一个新的硬件配置文件 试图为 Galaxy S8 S8 制作模拟器 我将屏幕尺寸设置为 5 8 6 2 英寸 取决于 S8 还是 S8 尽管事实上这似乎不会影响模拟器 屏幕分辨率设置为 1440 x 2960 就像设备一样 模拟器看
  • 如何将文件分成相等的部分而不破坏单独的行? [复制]

    这个问题在这里已经有答案了 我想知道是否可以将文件分成相等的部分 edit 除了最后一个之外都相等 而不破坏线 在 Unix 中使用 split 命令 行可能会分成两半 有没有一种方法可以将一个文件分成 5 个相等的部分 但仍然只包含整行
  • DirectoryInfo.EnumerateFiles(...) 导致 UnauthorizedAccessException (和其他异常)

    我最近需要枚举整个文件系统 寻找特定类型的文件以进行审计 由于对要扫描的文件系统的权限有限 这导致我遇到了一些异常 其中 最为普遍的是未经授权的访问异常 http msdn microsoft com en us library syste
  • 在 Visual Studio Code 中添加模块的 Python 路径

    我很难指定包含另一个目录甚至同一项目的文件夹中的模块 包的 python 路径 当我尝试导入时出现错误 ModuleNotFoundError 没有名为 感知 的模块 在 Spyder 中 这只需使用 UI 选择 python 将查找的附加
  • 这是一个通用函数指针吗?它危险吗?

    在学习和搞乱函数指针时 我注意到一种初始化 void 函数指针并强制转换它们的方法 然而 虽然我没有收到任何警告或错误 无论是使用 GCC 还是 VS 的编译器 我想知道这样做是否危险或不好的做法 因为我经常在网上看到这种初始化函数指针的方