C 中的“with”宏

2024-04-10

我一直在寻找一个类似于 with 结构的宏。 用法应该是这样的:

with (lock(&x), unlock(&x)) {
    ...
}

它可能对其他一些目的有用。

我想出了这个宏:

#define __with(_onenter, _onexit, v) \
    for (int __with_uniq##v=1; __with_uniq##v > 0; )\
        for (_onenter; __with_uniq##v > 0; _onexit) \
            while (__with_uniq##v-- > 0)

#define _with(x, y, z) __with(x, y, z)
#define with(_onenter, _onexit) _with(_onenter, _onexit, __COUNTER__)

它有 3 个嵌套循环,因为它应该:

  1. 初始化循环计数器(当然仅限 C99)
  2. 可能初始化变量_onenter(例如with (int fd=open(..), close(fd)))
  3. Allow break在代码块内。 (continue也是允许的。并且宏可以调整为assert() it out)

我在 XV6 操作系统的代码中使用了它,它看起来非常有用。

我的问题是 - 这样的宏最严重的问题是什么?我的意思是,除了单纯使用 C 宏(尤其是实现新的控制流构造的宏)之外。

到目前为止已经发现了这些缺点/问题:

  1. 不支持return or goto(但它可以节省一些goto内核代码中的 s)
  2. 不支持错误(例如fd < 0)。我认为这个是可以修复的。
  3. 仅限 gnu89 / c99 及以上版本(循环计数器。唯一变量技巧不是必需的)
  4. 比简单的锁定解锁效率稍低。我相信这是微不足道的。

还有其他问题吗?有没有更好的方法在 C 中实现类似的构造?


这个宏让我害怕。我更喜欢传统方法使用gotos http://blog.regehr.org/archives/894.

这种方法很原始,但大多数 C 程序员都熟悉该模式,如果不熟悉,他们可以通过阅读本地代码来理解它。不存在隐藏行为。结果,它是相当可靠的。

你的宏很聪明,但它对大多数人来说都是新的,并且它带有隐藏的陷阱。新的贡献者必须考虑诸如“不要return or goto从 with 块中“和”break会跳出 with 块,而不是跳出周围循环”。我担心错误会很常见。

如果您可以向编译器添加有关滥用此构造的警告,则平衡将会发生变化。随着铿锵 http://clang.llvm.org/docs/Tooling.html,这似乎是一个选择。在这种情况下,将检测到误用,并且您的代码仍可移植到其他编译器。

如果您愿意限制自己使用 GCC 和 Clang,您可以使用cleanup https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#Common-Variable-Attributes属性。这将使你的例子看起来像这样:

lock_t x = NULL __attribute__((cleanup(unlock)));
lock(&x);

And unlock当变量超出范围时,将使用指向该变量的指针来调用。这与其他语言功能集成,例如return and goto,甚至混合 C/C++ 项目中也有例外。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C 中的“with”宏 的相关文章

  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • WCF RIA 服务 - 加载多个实体

    我正在寻找一种模式来解决以下问题 我认为这很常见 我正在使用 WCF RIA 服务在初始加载时将多个实体返回给客户端 我希望两个实体异步加载 以免锁定 UI 并且我想利用 RIA 服务来执行此操作 我的解决方案如下 似乎有效 这种方法会遇到
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 不支持将数据直接绑定到存储查询(DbSet、DbQuery、DbSqlQuery)

    正在编码视觉工作室2012并使用实体模型作为我的数据层 但是 当页面尝试加载时 上面提到的标题 我使用 Linq 语句的下拉控件往往会引发未处理的异常 下面是我的代码 using AdventureWorksEntities dw new
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • 创建链表而不将节点声明为指针

    我已经在谷歌和一些教科书上搜索了很长一段时间 我似乎无法理解为什么在构建链表时 节点需要是指针 例如 如果我有一个节点定义为 typedef struct Node int value struct Node next Node 为什么为了
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • 覆盖子类中的字段或属性

    我有一个抽象基类 我想声明一个字段或属性 该字段或属性在从该父类继承的每个类中具有不同的值 我想在基类中定义它 以便我可以在基类方法中引用它 例如覆盖 ToString 来表示 此对象的类型为 property field 我有三种方法可以
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • cmake 将标头包含到每个源文件中

    其实我有一个简单的问题 但找不到答案 也许你可以给我指一个副本 所以 问题是 是否可以告诉 cmake 指示编译器在每个源文件的开头自动包含一些头文件 这样就不需要放置 include foo h 了 谢谢 CMake 没有针对此特定用例的
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • 如何在文本框中插入图像

    有没有办法在文本框中插入图像 我正在开发一个聊天应用程序 我想用图标图像更改值 等 但我找不到如何在文本框中插入图像 Thanks 如果您使用 RichTextBox 进行聊天 请查看Paste http msdn microsoft co
  • 如何防止用户控件表单在 C# 中处理键盘输入(箭头键)

    我的用户控件包含其他可以选择的控件 我想实现使用箭头键导航子控件的方法 问题是家长控制拦截箭头键并使用它来滚动其视图什么是我想避免的事情 我想自己解决控制内容的导航问题 我如何控制由箭头键引起的标准行为 提前致谢 MTH 这通常是通过重写

随机推荐

  • 如何在 Eclipse 中找到方法实现的用法?

    当我想在java中找到普通方法的用法时 这是相当简单和直接的CTRL SHIFT G 但是如果这个方法有一个super定义 实现 Eclipse 将向我展示层次结构类型中所有类型的用法 例如 如果我有一个toString 方法在我的类中 我
  • 将 ViewChild 用于动态元素 - Angular 2 和 ionic 2

    我想使用多个离子载玻片 https ionicframework com docs api components slides Slides 我动态添加的 但我不能使用 viewChild 请提出解决此问题的方法 模板 html div d
  • 如何使用 My.Settings.Save Visual Basic 保存窗体背景图像

    我正在尝试用 Visual Basic 创建一个操作系统 当然是基于程序的 它需要个性化 我希望用户能够从存储在项目资源中的一组选定图像中进行选择 并且我希望保存该图像 以便他们下次登录软件时 表单具有相同的他们选择保存的图像 额外的信息
  • python中的IOE错误“没有这样的文件或目录”

    我正在编写一个 Django 项目 涉及从表中检索数据 我有一个模块 它具有检索一些数据的行 snp data txt是模块同一目录中的文件 data file snp data txt 当我在 django 项目之外单独调用该模块时 该模
  • 整数求和布鲁斯,短+=短问题

    C 程序 short a b a 10 b 10 a a b Error Cannot implicitly convert type int to short we can also write this code by using Ar
  • 允许重复键并保持插入顺序的映射

    目前我正在使用 LinkedHashMap 来维护插入顺序 我使用的 LinkedHashMap 的语法 private LinkedHashMap
  • 防止mysql中的值变为负数的最佳方法

    我们有一个表 通过在该表中记录交易来维护帐户余额 即最近一行是帐户余额 在记录提款时 我们希望确保余额 永远不会出现负数 我们提出的解决方案类似于 INSERT INTO txns account id prev balance txn t
  • WinFORMS 中的 WPF 用户控件:项目结构

    SCENARIO 我决定为我的新应用程序使用 WPF 技术 必须通过从 WinForms 窗口单击菜单来调用此应用程序 因此 我创建了一个 WPF UserControl 库 并将其集成以使用 Element Host 在父 WinForm
  • 如何将数组转换为 UnsafeMutablePointer Swift 3.0?

    这是我在以前版本的 Swift 中的可行代码 let imageOptionsDictKeys kCVPixelBufferPixelFormatTypeKey kCVPixelBufferWidthKey kCVPixelBufferHe
  • 如何通过 lambda 函数 aws 发送和返回 JSON 响应

    我有一个名为 lambda 函数的 Amazon Webservices 闭包 其委托定义如下 def lambda handler event context logger info Ev s event if event action
  • 从 pandas 数据框中删除具有空值的行

    我正在尝试从数据框中删除一行 其中其中一列的值为空 我能找到的大部分帮助都与删除 NaN 值有关 到目前为止 这对我不起作用 我在这里创建了数据框 successfully crated data frame df1 ut get data
  • Opencv 图像拼接或全景

    我正在 OpenCV 全景 中进行图像拼接 但有一个问题 我无法使用 OpenCV 中的 Stitching 类 因此我必须仅使用特征点和单应性来创建它 OrbFeatureDetector detector minHessian std
  • querySelectorAll 是否支持 id 中的句点(.) 字符?

    querySelectorAll 是否支持 id 中的句点 字符 我的意思是如果我附加一个如下所示的元素 var div document createElement div div id my divid document body ap
  • Java 8 findFirst().isPresent() 比 count() > 0 更高效吗?

    鉴于我有一个流Stream
  • 如何在 CAFFE 的新网络中重复使用同一网络两次

    我有一个预训练的网络 我们称之为N 我想在新网络中使用两次 有人知道如何复制吗 然后我想为每个副本分配不同的学习率 例如 N1是第一个副本N N2是第二个副本N 新网络可能如下所示 N1 gt joint ip N2 gt layer 我知
  • 如何使用 vanilla JS 复制 useState

    Vanilla JS 中的代码的实现是什么 它允许我们像 React 中的 useState 那样声明和更新状态 const x setX useState 12 setX 14 console log x 14 这道题严格来说是get b
  • Android 1.5 多点触控

    有谁知道是否可以在 Android 1 5 设备上使用多点触控 我有一台 HTC Hero 它仍然运行 1 5 HTC 在推出 2 1 ROM 方面有点慢 Android MotionEvent 文档显示了常量 ACTION POINTER
  • android TextView:动态设置背景颜色不起作用

    以编程方式设置 Android 的背景颜色TextView似乎不起作用 我是不是漏掉了一些东西 TextView et new TextView activity et setText 350 et setBackgroundColor R
  • 使用 union 插入表变量

    我有一个表变量 我想插入联合查询 联合查询运行良好 但我似乎无法使插入工作 语法错误 INSERT INTO table a b c d VALUES SELECT a b c d FROM table1 UNION SELECT a b
  • C 中的“with”宏

    我一直在寻找一个类似于 with 结构的宏 用法应该是这样的 with lock x unlock x 它可能对其他一些目的有用 我想出了这个宏 define with onenter onexit v for int with uniq