使用宏构建 #include 指令的路径

2023-12-12

我希望包含由宏为程序的目标配置相关部分动态创建的文件路径。

例如,我想构造一个将像这样调用的宏:

#include TARGET_PATH_OF(header.h)

这将扩展为这样的内容:

#include "corefoundation/header.h"

当为 OSX 配置源时(在本例中)

到目前为止,所有尝试都失败了。我希望以前有人这样做过吗?

不起作用的示例:

#include <iostream>
#include <boost/preprocessor.hpp>

#define Dir directory/
#define File filename.h

#define MakePath(f) BOOST_PP_STRINGIZE(BOOST_PP_CAT(Dir,f))
#define MyPath MakePath(File)

using namespace std;

int main() {
    // this is a test - yes I know I could just concatenate strings here
    // but that is not the case for #include
    cout << MyPath << endl;
}

errors:

./enableif.cpp:31:13: error: pasting formed '/filename', an invalid preprocessing token
    cout << MyPath << endl;
            ^
./enableif.cpp:26:16: note: expanded from macro 'MyPath'
#define MyPath MakePath(File)
               ^
./enableif.cpp:25:40: note: expanded from macro 'MakePath'
#define MakePath(f) BOOST_PP_STRINGIZE(BOOST_PP_CAT(Dir,f))
                                       ^
/usr/local/include/boost/preprocessor/cat.hpp:22:32: note: expanded from macro 'BOOST_PP_CAT'
#    define BOOST_PP_CAT(a, b) BOOST_PP_CAT_I(a, b)
                               ^
/usr/local/include/boost/preprocessor/cat.hpp:29:36: note: expanded from macro 'BOOST_PP_CAT_I'
#    define BOOST_PP_CAT_I(a, b) a ## b
                                   ^
1 error generated.

我倾向于同意评论乌特纳皮斯蒂姆的回答即使你可以这样做,你也不应该这样做。但事实上,您可以使用符合标准的 C 编译器。 [注1]

There are two issues to overcome. The first one is that you cannot use the ## operator to create something which is not a valid preprocessor token, and pathnames do not qualify as valid preprocessor tokens because they include / and . characters. (The . would be ok if the token started with a digit, but the / will never work.)

实际上,您并不需要连接标记即可将它们与#运算符,因为该运算符将字符串化整个宏参数,并且该参数可能包含多个标记。然而,stringify 尊重空白[注 2],所以STRINGIFY(Dir File)行不通;这将导致"directory/ filename.h"文件名中的多余空格将导致#include失败。所以你需要连接Dir and File没有任何空格。

下面通过使用类似函数的宏来解决第二个问题,该宏仅返回其参数:

#define IDENT(x) x
#define XSTR(x) #x
#define STR(x) XSTR(x)
#define PATH(x,y) STR(IDENT(x)IDENT(y))
 
#define Dir sys/
#define File socket.h

#include PATH(Dir,File)

Warning:(感谢@jed 传递了这个问题。)如果连接的字符串包含在其他地方定义为宏的标识符,则此处将发生意外的宏替换。应小心避免这种情况,特别是如果Dir and/or File不受控制(例如,通过在编译器调用中定义为命令行参数)。

您还需要注意,某些实现可能会定义可能以类似标记的方式显示在文件路径中的单词。例如,GCC 可以定义具有如下名称的宏unix and linux除非使用显式 C 标准(不是默认标准)调用它。这可能是由类似的路径触发的platform/linux/my-header.h甚至linux-specific/my-header.h.

为了避免这些问题,如果您使用此技巧,我建议您:

  • 您使用符合 C(或 C11)标准的编译器设置,并且

  • 您可以将序列放在源文件的早期位置,最好是在包含任何其他标头或至少标准库之外的任何标头之前。

另外,您不需要复杂的IDENT宏,如果你可以编写没有空格的串联。例如:

#define XSTR(x) #x
#define STR(x) XSTR(x)

#define Dir sys
#define File socket.h

#include STR(Dir/File)

Notes

  1. 我用 clang、gcc 和 icc 尝试过,可以在godbolt。我不知道它是否适用于 Visual Studio。

  2. 更准确地说,它半尊重空白:空白被转换为单个空格字符。

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

使用宏构建 #include 指令的路径 的相关文章

  • 添加 Nullable int 时保持 null?

    我想添加可为空的int 并保留null当所有值都是null 我想要这个结果 1 2 3 1 null 1 null null null O null 0 问题是 如果我将一个值与 null 相加 结果为 null int i1 1 int
  • json.net自定义jobject反序列化

    我正在尝试使用 JsonConvert DeserializeObject string 将字符串反序列化为可与动态一起使用的 jobject 来动态访问 json 文档 但是我想避免知道文档的大小写 以便我可以输入 dynamic doc
  • 单元测试验证失败

    我正在运行我的单元测试PostMyModel路线 然而 在PostMyModel 我用的是线Validate
  • 检测wlan是否关闭

    任何人都可以给我一个提示 如何在 Windows Phone 上以编程方式检测 C 8 1 应用程序 不是 8 0 是否启用 禁用 WLAN 我不想更改这些设置 只是需要知道 该解决方案是一个 Windows 8 1 通用应用程序 Wind
  • 在开关中使用“goto”?

    我看到了一个建议的编码标准 内容如下Never use goto unless in a switch statement fall through 我不跟 这个 例外 案例到底是什么样的 这证明了goto 此构造在 C 中是非法的 swi
  • 计算另一个表达式中的 C# 表达式

    我想在另一个表达式中使用一个表达式 Expression
  • 为什么'enable_if'不能用于禁用这里声明

    include
  • 一元 +/- 运算符如何可能导致“-a”或“+a”中的整数提升,“a”是算术数据类型常量/变量?

    这句看似微不足道的台词摘自我的迈克 巴纳汉和布雷迪的 C 书 第 2 8 8 2 节 http publications gbdirect co uk c book chapter2 expressions and arithmetic h
  • 获取 boost Spirit 语法中的当前行

    我正在尝试使用 boostspirit 获取正在解析的文件的当前行 我创建了一个语法类和结构来解析我的命令 我还想跟踪在哪一行找到命令并将其解析到我的结构中 我将 istream 文件迭代器包装在 multi pass 迭代器中 然后将其包
  • 访问 ascx 文件中的母版页控件

    我有一个母版页文件 其中包含 2 个面板控件中的 2 个菜单 我还使用控件来检查用户是否登录并获取用户类型 根据我想要显示 隐藏面板的类型 控件本身不在母版页中引用 而是通过 CMS 系统动态引用 我想在用户控件中使用findcontrol
  • MFC:如何设置CEdit框的焦点?

    我正在开发我的第一个简单的 MFC 项目 但我正在努力解决一个问题 想要设置所有的焦点CEdit其中一个对话框中的框 我的想法是 当打开对话框时 焦点位于第一个编辑框上 然后使用 选项卡 在它们之间交换 我看到了方法SetFocus 但我无
  • 如何对 NServiceBus.Configure.WithWeb() 进行单元测试?

    我正在构建一个 WCF 服务 该服务接收外部 IP 上的请求并将其转换为通过 NServiceBus 发送的消息 我的单元测试之一调用Global Application Start 它执行应用程序的配置 然后尝试将 Web 服务解析为 验
  • 析构函数中的异步操作

    尝试在类析构函数中运行异步操作失败 这是代码 public class Executor public static void Main var c1 new Class1 c1 DoSomething public class Class
  • 使用 GCC 生成可读的程序集?

    我想知道如何使用GCC http en wikipedia org wiki GNU Compiler Collection在我的 C 源文件中转储机器代码的助记符版本 这样我就可以看到我的代码被编译成什么 你可以使用 Java 来做到这一
  • 英文日期差异

    接近重复 如何计算相对时间 https stackoverflow com questions 11 how do i calculate relative time 如何在 C 中计算某人的年龄 https stackoverflow c
  • .NET 4 的条件编译[重复]

    这个问题在这里已经有答案了 可能的重复 条件编译和框架目标 https stackoverflow com questions 2923210 c sharp conditional compilation and framework ta
  • 如何停止无限循环?

    我正在编写一个程序 该程序将计算三角形或正方形的面积 然后提示用户是否希望计算另一个 我的代码已经运行到可以计算任一形状的面积的程度 但随后不再继续执行代码的其余部分 例如 如果选择了正方形 则计算面积 然后返回到正方形边长的提示 我假设这
  • CUDA 8 编译错误 -std=gnu++11

    我正在尝试转换一些代码以使用 CUDA 并且我认为我遇到了兼容性问题 我们使用CMake 这些是我使用的 gcc 和 CUDA 版本 gcc version gcc Ubuntu 5 4 0 6ubuntu1 16 04 5 5 4 0 2
  • 如何将 SQL“LIKE”与 LINQ to Entities 结合使用?

    我有一个文本框 允许用户指定搜索字符串 包括通配符 例如 Joh Johnson mit ack on 在使用 LINQ to Entities 之前 我有一个存储过程 该存储过程将该字符串作为参数并执行以下操作 SELECT FROM T
  • 如何使用placement new重新初始化该字段?

    我的课程包含字段 private OrderUpdate curOrderUpdate 我一遍又一遍地使用它 经常需要重新初始化 for int i 0 i lt entries size i auto entry entries i ne

随机推荐

  • Yii2 如何从 url 中删除站点/索引和页面参数

    我在默认页面上使用分页 即在 yii2 中的站点 索引上 所以链接器为分页生成的 URL 看起来像这样 domain com site index page 1 我想删除站点 索引和页面参数 使其如下所示 domain com 1 我尝试在
  • WPF 网格水平对齐不起作用。尺寸不变

    我有一个堆栈 堆栈内有一个网格 当我调整窗口大小时 我需要增加堆栈和网格大小 我将 Stack 和 Grid Horizo ntalAlignment 设置为 拉伸 堆栈工作正常 但当我调整窗口大小时 网格大小不会增加 这是我的代码
  • TensorFlow 索引无效(越界)

    您好 我目前正在尝试使用自己的图像数据运行 TensorFlow 但是当我尝试运行这些函数时它崩溃了 它来自 mnist py def loss fn logits labels batch size tf size labels labe
  • opengl:如何避免纹理缩放

    我该如何申请重复无论应用的顶点数据如何 纹理始终保持其原始比例 纹理中的 1 个像素 屏幕上的 1 个像素 我意识到这不是最常见的任务 但是是否可以轻松设置 opengl 来执行此操作 或者我是否需要对尊重其原始外观的顶点数据应用某种掩码
  • java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法以选择 sqlite

    我是安卓世界的新手 我的编码有问题 这只是一个小错误 我不知道它不起作用 即使我改变了其他方法 但错误仍然是相同的错误 这里的错误发生在logcat java lang NullPointerException Attempt to inv
  • 使用 DOM 选项定位 DataTables 元素

    我无法正确定位l长度变化和f分别过滤我的右上角和左下角的输入DT datatable输出在shiny使用dom选项 代码 library shiny library DT set seed 2282018 company lt data f
  • Firebase - 限制特定用户的文件访问权限

    我正在尝试使用 Firebase 实现以下行为 用户使用 Firebase 身份验证登录 用户将文件上传到 Firebase 存储 用户输入不同用户的电子邮件地址 该用户帐户可能已经存在 如果没有 收件人会收到一封电子邮件 提示他们注册 上
  • 在不使用 LINQ 或委托的情况下对 C# 列表 <> 进行排序

    我有一个对象列表 每个对象在 3D 空间中都有一个位置 我需要按到任意点的距离对这个列表进行排序 目前我正在这样做 attachedEffectors attachedEffectors OrderBy x gt Mathf Pow x t
  • 使用 Cypher 从 Neo4j 图中提取子图

    假设我在 Neo4j 中有一个包含 5 个节点的集合 使得集合中的每个节点都连接到集合中的至少一个其他节点 我想从 Neo4j 中提取由节点集合及其交互形成的子图 目前 我正在使用一种非常原始的方法 该方法涉及尝试找到系统中每个节点与其他每
  • 在列表视图中选择 edittexts 文本。怎么办呢?我不知道

    我有一个 ListView 每行都有一个 EditText 正在工作 我需要在单击编辑文本时选择此文本以写入数字 而无需删除或移动光标 首先使用 selectAllonfocus 有效 但是 滚动列表视图后 EditText 变得疯狂并且选
  • 如何安全地处理自定义编写的 PowerShell cmdlet 中的密码?

    假设我有一个自定义 PowerShell Cmdlet 用于导出数据并使用密码对其进行加密 Cmdlet VerbsData Export SampleData public class ExportSampleData PSCmdlet
  • React Native DateTimePicker 的日期格式?

    我正在使用 React Native DateTimePicker https github com react native datetimepicker datetimepicker The onChange事件有时间戳 但我不明白它的
  • 我想在 flutter 中访问我的系统铃声

    有什么办法可以得到所有的铃声手机使用的flutter 并将所选铃声设置为我的应用程序的默认铃声 提前致谢 我设法使用本机代码完成它 首先 您将在 Flutter 端创建这些东西 here where your ringtones will
  • nuxtjs 在点击元素时添加和删除类

    我是 vue 和 nuxt 的新手 这是我需要更新的代码
  • 在win7-64位中通过mingw使用boost.python编译一些代码

    我决定让我的程序兼容windows环境 但是我在windows上的编程经验很少 有一些错误需要帮助 环境 操作系统 win7 64位 IDE 代码块12 11 python Python 2 7 3 Windows X86 64 安装程序
  • googleapi:错误 403:需要“compute.organizations.enableXpnHost”权限

    我已在组织级别为我的用户授予我的管理员用户和服务帐户用户 计算共享 VPC 管理员 角色 但我似乎无法启用请求的权限 我还授予了拥有 namidalab dev networks 项目的文件夹级别的角色 在 IAM 和管理控制台 UI 中选
  • 获取单个 NSDateComponents 的 2 个日期之间的确切差异

    如何获得两个值之间的精确差异 以十进制表示 NSDate Eg 2016 年 1 月 15 日 to 2017 年 7 月 15 日 1 5年 我可以使用类似的东西 NSCalendar currentCalendar components
  • 在 awk 中对块内的行进行排序

    我有一个很长的文件 其中包含依赖项列表 它们的版本以及依赖项所属的服务 该文件按块排序和分隔 这是我引用的文件文件的片段 foo bar baz json jar 2 2 2 compile service ServiceTwo foo b
  • 如何在 JPanel 中为矩形设置动画?

    我想为我的项目学习一些有关 JAVA 的技巧 我想从左到右 从右到左对我的矩形进行动画处理 但我无法对球动画应用相同的功能 另外 如何以 y 坐标边框在不同的 x 方向上启动我的球 非常感谢您的建议和帮助 我的代码 import javax
  • 使用宏构建 #include 指令的路径

    我希望包含由宏为程序的目标配置相关部分动态创建的文件路径 例如 我想构造一个将像这样调用的宏 include TARGET PATH OF header h 这将扩展为这样的内容 include corefoundation header