用宏包装函数(无需重命名)C

2024-05-06

我有兴趣通过包装现有函数调用来添加一些额外的逻辑without重命名它们。(仅供测试).

我发现的现有解决方案依赖于将函数包装在不同名称的宏中,这可能意味着更改大量代码。

有什么建议么?


请注意,我知道LD_PRELOAD,但我有兴趣使用宏来检查传递给函数的参数(使用_Generic例如)。


通常不需要重命名宏包装函数,因为在宏的扩展内部,宏的名称不会扩展。

这是直接来自 C11 标准的示例:

#define cbrt(X) _Generic((X),               \
                        long double: cbrtl, \
                        default: cbrt,      \
                        float: cbrtf        \
                        )(X)

当然,如果你这样做,你就会遇到问题#include <tgmath.h>因为在这种情况下,您已经拥有类型通用宏,例如上面的宏,并且您将无法重新定义sqrt(除非你#undef它)。而且你必须#include <math.h>在定义该宏之前。

即便如此,你仍如履薄冰。该标准保留了标准库函数的名称,并坚持(§7.1.3/2):

如果程序在保留标识符的上下文中声明或定义标识符(7.1.4 允许的除外),或者将保留标识符定义为宏名称,则行为未定义。

引用的第 7.1.4 节确实允许您#undef一个类似于函数的宏,它隐藏了标准库函数,但我不清楚您是否可以随后重新定义它。 YMMV。


如果你想使用_Generic要调用包装函数,您仍然可以在不重命名原始函数的情况下使其工作。例如:

#include <nanny.h>

/* In this file, you can't call nanny(char), and if you call it
 * with an unsigned argument, we'll insert an additional check
 */

#define nanny(X) _Generic((X), int: nanny, unsigned:nanny_wrapper)(X)

int nanny_wrapper(unsigned x) {
  assert(x < INT_MAX);
  /* The redundant parentheses prevent macro expansion */
  return (nanny)(x);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用宏包装函数(无需重命名)C 的相关文章

随机推荐

  • JSON 和 JavaScript 对象有什么区别? [复制]

    这个问题在这里已经有答案了 我对 JSON 和 JavaScript 对象很陌生 有人可以解释一下 JSON 和 JavaScript 对象之间的区别吗 它们的用途是什么 这个比那个好吗 还是要看情况而定 何时使用哪一个 在什么情况下使用
  • ios 将 alpha 通道视频叠加在另一个视频上

    我一直在尝试创建一个视频模板 该模板使用 alpha 通道视频叠加在 mp4 视频和图像上 这就是我需要创建视频的方式http viewptch ptchcdn com rendered 52b28a9f8d4f980f3a3f99c3 c
  • 如何使用 HTML/CSS/jQuery 编写复数分数?

    我希望能够使用 HTML CSS jQuery 编写分数 而不是使用 TeX 渲染器甚至 MathML 目前 有一个很好的解决方法可以编写简单的分数 如果您有one term对于分子和分母来说 但是一旦你开始使用多个术语 它看起来就相当可怕
  • mockito:如何在java 8中匹配可变参数?

    我正在努力将项目从 java 7 迁移到 8 并且在 Mockito 何时 情况下遇到编译错误 我很难追踪 when queryRunner query any String class any ResultSetHandler class
  • 为什么即使显式抛出错误也没有被捕获?

    我想使用带注释的 ExceptionHandler 捕获 SpringMVC3 中的 错误 我可以捕获可抛出异常和任何异常 但是当我尝试使用 Error 时 它没有捕获异常 知道为什么吗 下面的代码演示了这个问题 Controller Re
  • $PATH 中 /usr/bin 和 /usr/local/bin 等的顺序

    在我的 Mac 上 我经常使用 bash 对于我的环境设置 我添加了 usr bin and usr local bin into PATH就像我平常做的那样 虽然我知道什么 usr bin and usr local bin关于 我很好奇
  • Android 手机号码验证

    如何检查电话号码是否有效 长度最大为13 包括字符 在前 我怎么做 我试过这个 String regexStr 0 9 String number entered number getText toString if entered num
  • 如果我从 python 中的多个不同进程登录到同一个文件,会发生什么?

    我花了几个小时来挖掘这种行为 首先是关于这些问题 write 2 到本地文件系统的原子性 https stackoverflow com questions 10650861 atomicity of write2 to a local f
  • 如何在我的项目中使用 FFTW DLL 导入库 .lib 作为静态 .lib?

    我了解 C 和编译小型插件 始终基于类似且布局的工作流程 虽然目前我需要将最新版本的 FFTW 编译成静态库 或者从编译版本中获取它 这应该会容易得多 但这给了我一个非常困难的时间 可能是因为我不知道编译的来龙去脉 请注意 我正在使用 Vi
  • 在慢速连接上使用 picasso 加载图像

    我正在使用 Picasso 加载列表视图的图像 问题是互联网连接速度很慢 如何更改 Picasso 中的加载超时时间 我的代码是 Picasso with context load MainActivity WEBSITE book ite
  • mongoDB 对嵌套对象数组的聚合查找

    我有一个如下所示的集合 但我无法执行 lookup 并按开始时的方式返回它 但包含填充的字段 我已经对我想要填充的字段发表了评论 代理 missions clients client title Tourn e libre agent 5d
  • 如何仅重置 Angular 5 中表单的特定字段

    我在我的组件文件之一中创建了一个函数来重置表单 myform onSubmit if this myform valid console log Form Submitted this myform reset 它可以很好地重置整个表单 但
  • 想要运行命令列表,但能够在运行时编辑该列表

    我有一个要运行的 bash 命令列表
  • 使 Flex 子项的高度等于网格列内父项的高度

    我正在尝试构建一个定价表 其中每列都包含一张卡片 我希望所有卡片都拉伸到其父 col 元素的高度 注意 我正在使用 Bootstrap 4 并尝试使用现有的网格系统来实现这一点 为了保持一致性 并使用这个特定的标记 我无法让卡片增长到其父容
  • 如何使用 Asp.Net MVC 3 和 Razor 获得特定于视图的 内容?

    除了 Layout cshtml 中已链接的内容之外 我还想在某些视图中链接特定的样式表 对于非 Razor 我看到使用内容占位符 我该如何为 Razor 执行此操作 Razor 中的内容占位符相当于部分 在你的 Layout cshtml
  • /usr/sbin/install 到底有什么作用?

    我正在尝试安装discount https github com Orc discount on my VPS http no de它基于Solaris 设置一些环境变量后编译效果很好 但是安装失败 https gist github co
  • Web 本地应用程序 Apache:运行 shell 脚本

    我开发了一个 shell 脚本 我想用它创建一个 UI 我决定使用带有本地服务器的 Web 界面 因为我对 HTML PHP 的了解很少 比 QT 或 Java 的了解更多 我只是希望我的 html 可以在我的计算机上运行 shell 脚本
  • 如何使用文本框在数据网格视图中搜索数据?

    这是我当前的代码 private void searchTextBox TextChanged object sender EventArgs e dataGridView1 DataSource as DataTable DefaultV
  • Chrome DevTools 中的渲染去了哪里?

    看起来渲染设置不再是原来的位置 即启用绘画闪烁 显示图层边框 显示 FPS 仪表 显示滚动性能问题 我怎样才能再次访问这些功能 渲染设置已移动铬48 您现在可以通过三点菜单图标 更多工具 渲染设置来访问它们 或者 您可以通过底部窗格的新菜单
  • 用宏包装函数(无需重命名)C

    我有兴趣通过包装现有函数调用来添加一些额外的逻辑without重命名它们 仅供测试 我发现的现有解决方案依赖于将函数包装在不同名称的宏中 这可能意味着更改大量代码 有什么建议么 请注意 我知道LD PRELOAD 但我有兴趣使用宏来检查传递