使用 #define-d 列表作为 C 预处理器宏的输入

2023-12-12

在一个示例项目中,我定义了宏

#define FOO(x, y) x + y   .

这效果非常好。例如,FOO(42, 1337)被评估为1379.

但是,我现在想使用另一个#define:

#define SAMPLE 42, 1337

当我现在打电话时FOO(SAMPLE),这行不通。编译器告诉我FOO接受两个参数,但仅使用一个参数调用。

我猜想这样做的原因是,虽然宏的参数是在函数本身之前评估的,但预处理器在评估后不会再次解析整个指令。这类似于不可能从宏输出额外的预处理器指令的事实。

有没有可能获得所需的功能?

更换FOO带有 C 函数的宏是不可能的。原始宏位于我无法更改的第三方代码中,它输出一个以逗号分隔的值列表,可直接在数组初始值设定项中使用。因此,C 函数无法复制相同的行为。

如果使用简单的方法无法完成此任务:您将如何存储(x, y)以可维护的形式配对?就我而言,有 8 个参数。因此,将各个部件单独存放#define-s 也不容易维护。


您遇到的问题是预处理器未按照您想要的顺序匹配和扩展宏。现在,您通常可以通过插入一些额外的宏来强制它获得正确的顺序来让它执行您想要的操作,但为了做到这一点,您需要了解正常的顺序是什么。

  • 当编译器看到带有参数的宏名称后跟(它首先扫描该参数列表,将其分解为参数,而不识别或扩展参数中的任何宏。

  • 解析和分离参数后,它会重新扫描每个参数的宏,并扩展在该参数中找到的任何参数,除非该参数与# or ##在宏观体

  • 然后它用(现在可能扩展的)参数替换主体中参数的每个实例

  • 最后,它重新扫描主体以查找主体中可能存在的任何其他宏以进行扩展。在这一次扫描中,原始宏将不会被识别和重新扩展,因此您不能进行递归宏扩展

因此,您可以通过仔细使用 EXPAND 宏来获得您想要的效果,该宏接受单个参数并对其进行扩展,从而允许您在过程中的正确位置强制进行额外的扩展:

#define EXPAND(X)   X
#define FOO(x,y)    x + y
#define SAMPLE      42, 1337

EXPAND(FOO EXPAND((SAMPLE)))

在这种情况下,您首先在参数列表中显式展开宏,然后手动展开生成的宏调用。

按问题海报更新

#define INVOKE(macro, ...) macro(__VA_ARGS__)

INVOKE(FOO, SAMPLE)

提供了一个扩展的解决方案,可以在不使代码混乱的情况下工作EXPANDs.

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

使用 #define-d 列表作为 C 预处理器宏的输入 的相关文章

  • 用于代数简化和求解的 C# 库 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 网络上有很多代数求解器和简化器 例如 algebra com 上不错的代数求解器和简化器 然而 我正在
  • 在 C++ 中使用 matlab 结构(matlab 函数调用的返回值)(由 matlab 编译器生成的库)

    你好 我有一个相当简单的 matlab 函数 例如 function MYSTRUCT myfunc MYSTRUCT prop1 test MYSTRUCT prop2 foo MYSTRUCT prop3 42 end 我用 matla
  • Directory.Delete 之后 Directory.Exists 有时返回 true ?

    我有非常奇怪的行为 我有 Directory Delete tempFolder true if Directory Exists tempFolder 有时 Directory Exists 返回 true 为什么 可能是资源管理器打开了
  • 如何让 Swagger 插件在自托管服务堆栈中工作

    我已经用 github 上提供的示例重新提出了这个问题 并为任何想要自己运行代码的人提供了一个下拉框下载链接 Swagger 无法在自托管 ServiceStack 服务上工作 https stackoverflow com questio
  • 如何将非静态类成员“std::bind”绑定到 Win32 回调函数“WNDPROC”?

    我正在尝试将非静态类成员绑定到标准WNDPROC http msdn microsoft com en us library ms633573 aspx功能 我知道我可以通过将类成员设为静态来简单地做到这一点 但是 作为一名 C 11 ST
  • 复制 std::function 的成本有多高?

    While std function是可移动的 但在某些情况下不可能或不方便 复制它会受到重大处罚吗 它是否可能取决于捕获变量的大小 如果它是使用 lambda 表达式创建的 它依赖于实现吗 std function通常被实现为值语义 小缓
  • C中的malloc内存分配方案

    我在 C 中尝试使用 malloc 发现 malloc 在分配了一些内存后浪费了一些空间 下面是我用来测试 malloc 的一段代码 include
  • 在 C 中匹配二进制模式

    我目前正在开发一个 C 程序 需要解析一些定制的数据结构 幸运的是我知道它们是如何构造的 但是我不确定如何在 C 中实现我的解析器 每个结构的长度都是 32 位 并且每个结构都可以通过其二进制签名来识别 举个例子 有两个我感兴趣的特定结构
  • 使用 LINQ2SQL 在 ASP.NET MVC 中的各种模型存储库之间共享数据上下文

    我的应用程序中有 2 个存储库 每个存储库都有自己的数据上下文对象 最终结果是我尝试将从一个存储库检索到的对象附加到从另一个存储库检索到的对象 这会导致异常 Use 构造函数注入将 DataContext 注入每个存储库 public cl
  • qdbusxml2cpp 未知类型

    在使用 qdbusxml2cpp 程序将以下 xml 转换为 Qt 类时 我收到此错误 qdbusxml2cpp c ObjectManager a ObjectManager ObjectManager cpp xml object ma
  • 从 Linux 内核模块中调用用户空间函数

    我正在编写一个简单的 Linux 字符设备驱动程序 以通过 I O 端口将数据输出到硬件 我有一个执行浮点运算的函数来计算硬件的正确输出 不幸的是 这意味着我需要将此函数保留在用户空间中 因为 Linux 内核不能很好地处理浮点运算 这是设
  • 如何检测表单的任何控件的变化?

    如何检测 C 中表单的任何控件的更改 由于我在一个表单上有许多控件 并且如果表单中的任何控件值发生更改 我需要禁用按钮 我正在寻找一些内置函数 事件处理程序 属性 并且不想为此创建自定义函数 不 我不知道任何时候都会触发任何事件any控制表
  • Qt - ubuntu中的串口名称

    我在 Ubuntu 上查找串行端口名称时遇到问题 如您所知 为了在 Windows 上读取串口 我们可以使用以下代码 serial gt setPortName com3 但是当我在 Ubuntu 上编译这段代码时 我无法使用这段代码 se
  • 如何在 Xaml 文本中添加电子邮件链接?

    我在 Windows Phone 8 应用程序中有一些大文本 我希望其中有电子邮件链接 例如 mailto 功能 这是代码的一部分
  • C#:帮助理解 UML 类图中的 <>

    我目前正在做一个项目 我们必须从 UML 图编写代码 我了解 UML 类图的剖析 但我无法理解什么 lt
  • 等待进程释放文件

    我如何等待文件空闲以便ss Save 可以用新的覆盖它吗 如果我紧密地运行两次 左右 我会得到一个generic GDI error
  • C++ 函数重载类似转换

    我收到一个错误 指出两个重载具有相似的转换 我尝试了太多的事情 但没有任何帮助 这是那段代码 CString GetInput int numberOfInput BOOL clearBuffer FALSE UINT timeout IN
  • WebSocket安全连接自签名证书

    目标是一个与用户电脑上安装的 C 应用程序交换信息的 Web 应用程序 客户端应用程序是 websocket 服务器 浏览器是 websocket 客户端 最后 用户浏览器中的 websocket 客户端通过 Angular 持久创建 并且
  • 从列表中选择项目以求和

    我有一个包含数值的项目列表 我需要使用这些项目求和 我需要你的帮助来构建这样的算法 下面是一个用 C 编写的示例 描述了我的问题 int sum 21 List
  • 当我使用 OpenSSL1.1.0g 根据固定的 p 和 g 值创建 Diffie Hellman 密钥协议密钥时,应该执行哪些检查?

    您好 我尝试通过这段代码使用修复 p 和 g 参数来制作 Diffie Hellman Keysanswer https stackoverflow com a 54538811 4706711 include

随机推荐

  • 收据对齐无法快速正常工作

    我目前正在根据我的数据打印收据 当我打印收据时 对齐数据无法正常工作 我认为我应该将开始索引和结束索引应用于字符串 因为我的产品名称长度不同 所以我应用此代码来检查字符串的长度 这是收据的屏幕截图 你可以看到收据对齐是错误的 这是我的代码
  • 依赖注入简单实现

    看完之后this我想知道是否有人可以帮助我理解如何使用这些 PHP 类正确实现依赖注入 class DBClass private mMysqli function construct mysqli database this gt mMy
  • 使用 InputBox 将额外的搜索文本添加到 MediaWiki 搜索查询

    我们正在使用InputBox扩大 我们希望有一个使用两个复选框的搜索功能 如下所示 因此 用户可以选择任一 一个或两个引用页面上特定文本的复选框 也就是说 如果用户选择 平台 1 0 则搜索将返回页面上带有 平台 1 0 的页面 实际上 它
  • FtpWebrequest - 文件名包含德语“Umlaute”,例如 ä,ö

    我尝试根据 FtpWebrequest 通过 FTP 获取文件 当文件名包含德语变音符号 如 时 下载失败 Code FtpWebRequest request2 FtpWebRequest WebRequest Create ftp re
  • std::cout 不在 for 循环内工作

    我是 C 的新手 现在我正在从名为 C 的书中学习加速C 我完成了第三章 向量 我来到了这个练习 编写一个程序来计算每个不同单词在其输入中出现的次数 经过一番思考后 我开始着手做这件事 我想测试该程序 但 std cout 不起作用 我放c
  • Array.fill(Array) 通过引用而不是通过值创建副本[重复]

    这个问题在这里已经有答案了 我正在尝试使用创建 6 x 12 矩阵Array fill let m Array 6 fill Array 12 fill 0 虽然这有效 但问题是内部数组实际上都引用相同的Array object let m
  • 频谱图及其是什么

    我很想知道右上角的数字 http en wikipedia org wiki Spectrogram 是生成的 脚本 以及如何分析它 即它传达什么信息 我希望能用最少的数学术语得到简化的答案 谢谢 该图沿水平轴显示时间 沿垂直轴显示频率 用
  • 如何通过代码输入日期类型打开窗口

    span t date span
  • H2DB 的默认 URL 和凭据?

    我在 springBoot 应用程序中添加了 H2DB 以进行单元测试 在 application test properties 中我刚刚添加了 spring datasource name h2db spring h2 console
  • 两列之间的排序差异

    我有两列 购买王子和销售价格 我想计算它们之间的差异 之后我想订购结果 这样我就可以看到所有的利润率 我可以只用一条 SELECT 语句来完成吗 Thanks SELECT sale price buy price AS profit FR
  • 如何在 iOS 中的 UITextView 中添加toggleBoldface 选项?

    我希望将toggleBoldface toggleItalics 和toggleUnderline 添加到UITextView 的编辑选项中 如何才能做到这一点 最好使用 Swift 启用文本视图allowsEditingTextAttri
  • 单击文本时就像“Ctrl+A”一样选择文本吗?

    我想在单击或双击时选择段落中的文本 p 标签 不是高亮 就像用鼠标划出一个选择区域来选择要选择的文字一样 我在页面上有几个段落和 rar 文件链接地址 我想在单击其中之一时选择所有文本 我认为文本框可以这样工作 但我喜欢它位于段落或链接标记
  • 将 2 个 matlab 图合并为 1 - 如何使用 copyobj 使用颜色、线宽等

    我想加载 2 个数字并将它们合并为一个 我知道我可以通过将一个图形复制粘贴到另一个图形来完成此操作 但是通过脚本吗 I saw this 但它产生了 2 个数字 我如何将它们合并为一个 例如使用 Hold on 另外 我可以更改一张图中的轴
  • 将 .txt 文件中的整数读入 numpy 数组

    我正在尝试从简单的 text 数组中读取 4 个整数 如本问题所述genfromtxt 从空格分隔的 txt 文件中读取整数 但我想要它作为 2D numpy 数组 def read data data np genfromtxt Skin
  • 创建 JWT 令牌时出错

    当我正在从使用传统标头身份验证方法到智威汤逊令牌方法 我用了下面的例子发现here 但是 我收到以下错误 Error calling Login errorCode PARTNER AUTHENTICATION FAILED message
  • 如何高效地使用Enum对象作为Map数据结构中的键?

    是否有更高效 更专业的 Map 集合实现 其中 Enum 对象可以用作键 Yes EnumMap正是如此 的有效实施Map接口 其中键类型必须是枚举 来自API documentation Class EnumMap
  • javascript 预加载任何在 Chrome 中不起作用的图像

    我对网页设计相当陌生 我刚刚创建了以下网站http www janewaltonwatercolours co uk 除了一些小故障之外 它适用于所有浏览器 然而 在 Chrome 中 我用于预加载图像的 javascript 函数无法正常
  • 如何“取消设置”事件

    如果我在 Designer cs 页面中设置了组合框单击事件 然后在程序运行期间的某个时刻 基于某些条件 我不再希望设置组合框单击事件 如何 取消设置 它 我尝试过comboboxname Click null 并尝试将其设置为另一个不执行
  • 我如何在 ClearCase 中列出推荐的基线

    我目前正在编写一个脚本 该脚本必须检查集成流的推荐基线 因此我知道的唯一参数是流名称 我想知道是否有办法在 Linux 上使用cleartool 来做到这一点 bash 脚本 这是我的视频 And this is the Stream 您可
  • 使用 #define-d 列表作为 C 预处理器宏的输入

    在一个示例项目中 我定义了宏 define FOO x y x y 这效果非常好 例如 FOO 42 1337 被评估为1379 但是 我现在想使用另一个 define define SAMPLE 42 1337 当我现在打电话时FOO S