在 C 编译时检查类型是结构体还是指针?

2024-04-04

注意:这是NOTPaul T 链接的问题的重复项,因为我问是否可以在编译时确定类型是否属于某种更广泛的不完整类型/种类,而不是在编译时是否已注册符号。这似乎是对这个问题的根本误解。

我正在用 C 编写一个库,该库处理伪通用函数,该函数通过宏包装器将类型作为参数。

为了节省细节(因为它们相当复杂),我认为有两个可能的功能可以提供帮助:

  • 能够在编译时检测类型是否是指针。 (不,“使用 _Generic 来测试是否从减法中获得 ptrdiff_t”技巧不起作用,因为结构是一种可能性,并且您不能减去结构。)

  • 能够在编译时检测类型是否是结构。 (如果这是可能的,那么如果检测到类型不是结构,则可以使用前面提到的 _Generic 技巧。)

我已经在 Godbolt 上尝试了我能想到的一切(甚至尝试将类型与不完整的匿名结构进行比较并尝试使用 __builtin_types_completed_p),但无法找到任何解决方案。

如果有人有任何解决方案,我很乐意看到它们,否则我最终可能不得不使设计变得复杂一些——所以如果不可能,那也不是世界末日,但如果可以做到,那就太理想了。

为了大致了解这些宏之一的外观或其预期输出:

int *a;
assert(!IS_STRUCT(a));
assert(IS_POINTER(a));
struct {} b;
assert(IS_STRUCT(b));
assert(!IS_POINTER(b));

不应该抛出任何错误。


完整答案(如果使用 EDG 前端):

如果您的 IDE/编译器正在使用 EDG C++ 前端(很多都是这样),并且您正在使用C,而不是 C++ (您的标签建议),并且您说您正在使用 typeof,那么您可以检测如下结构(请参阅最新手册,第 75 页 https://www.edg.com/docs/edg_cpp.pdf):

/* Test if EDG Front End is used*/
#if defined(__EDG__) && defined(__EDG_VERSION__)
#define IS_STRUCT(expression_or_type_name) __is_class(typeof (expression_or_type_name)))
#endif

自从在C __is_class()仅适用于struct (http://www.cplusplus.com/reference/type_traits/is_class/ http://www.cplusplus.com/reference/type_traits/is_class/).

此外,指针可以类似地检测如下:

/* Test if EDG Front End is used*/
#if defined(__EDG__) && defined(__EDG_VERSION__)
#define IS_POINTER(expression_or_type_name) (__is_convertible_to(typeof (expression_or_type_name), void*) || __is_convertible_to(typeof (expression_or_type_name), void const*) || __is_convertible_to(typeof (expression_or_type_name), void volatile*) || __is_convertible_to(typeof (expression_or_type_name), void const volatile*))
#endif

(http://www.cplusplus.com/reference/type_traits/is_convertible/ http://www.cplusplus.com/reference/type_traits/is_convertible/)

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

在 C 编译时检查类型是结构体还是指针? 的相关文章

  • 如何自定义 DataTable 列的排序

    我需要对数据表列的值进行排序 该列包含字符串 整数或混合文本 例如 数据表列包含如下值 23 18 12 store 23 store a1 1283 25 如果我使用对值进行排序Dataview sort 方法会按此顺序产生 12 128
  • LINQ to XML - 如何正确使用 XDocument

    现在我首先要说的是 这确实是一项任务 然而 在我遇到 Linq to XML 语法之前 我几乎已经完成了它 我有 2 个课程 曲目和 CD 现在作为作业的一部分 我创建了一张 CD 然后向其中添加了一些曲目 在搜索了大量完美解释了如何从 x
  • 如何在 C# 事件中区分更改是由代码还是由用户进行?

    我有一个简单的TextBox一开始是空的 我有一个简单的事件 TextChanged 可以知道用户何时更改了其中的任何内容TextBox 但是 如果我自己在代码中对其执行任何操作 该事件就会触发 喜欢设置textbox Text Test
  • boost线程在中断时不打印退出消息

    我有这段代码用于执行三个线程 其中第二个线程应在按 Enter 时中断并打印退出消息 void input val DO STUFF return void process val DO STUFF try cout lt lt waiti
  • 实体框架代码优先 - 在另一个文件中配置

    使用 Fluent API 将表到实体的映射分开的最佳方法是什么 以便它全部位于单独的类中 而不是内联在 OnModelCreating 方法中 我目前在做什么 public class FooContext DbContext prote
  • 有没有比这更快的方法来查找目录和所有子目录中的所有文件?

    我正在编写一个程序 需要在目录及其所有子目录中搜索具有特定扩展名的文件 这将在本地驱动器和网络驱动器上使用 因此性能是一个问题 这是我现在使用的递归方法 private void GetFileList string fileSearchP
  • 身份未映射异常

    System Security Principal IdentityNotMappedException 无法转换部分或全部身份引用 该错误仅在应用程序注册后出现一次 当 SecurityIdentifier 无法映射时 例如 返回 Ide
  • 使用 VSTO 更改 Outlook 设置

    我刚刚花了大约 4 个小时试图弄清楚如何以编程方式检索 设置 Microsoft Outlook 2010 的 Outlook 设置 我所说的 设置 是指文件 选项 邮件下的设置 我想做的是检索用户设置的设置列表 自动化我们每天需要在某些消
  • C++ 在 Vector 中使用不可分配的对象

    我想将对象列表存储在std vector 但对象包含引用且无法分配给 但是 我可以复制构造该对象 我能想到的唯一选择是使用指针来包装对象并在需要分配指针时重新设置指针 但这样做的语法会显着降低可读性 特别是在使用迭代器时 我更喜欢另一种选择
  • 根据拦截和返回值自动重试客户端WCF调用

    是否可以拦截 WCF 调用的结果并重试该操作 例如 操作的返回值可能包含状态代码 指示我传递到原始调用的会话令牌已过期 在这种情况下 我可以检索新的会话令牌并使用新的会话令牌重试调用 是否可以通过使用 WCF 拦截返回值 检查它 然后以对操
  • 在生产者-消费者情况下使用条件变量

    我正在尝试了解条件变量以及如何在生产者 消费者情况下使用它 我有一个队列 其中一个线程将数字推入队列 而另一个线程从队列中弹出数字 当生产线程放置一些数据时 我想使用条件变量向消费线程发出信号 问题是有时 或大多数时候 它只将最多两个项目推
  • 为什么以下代码不允许我使用 fgets 获取用户输入但可以使用 scanf?

    这是一个更大程序的简短摘录 但该程序的其余部分无关紧要 因为我认为我能够隔离该问题 我怀疑这与我使用 fgets 的方式有关 我读过 最好使用 fgets 而不是 scanf 但我似乎无法让它在这里正常工作 当我使用以下代码时 程序不会给我
  • 用 C# 编写的带有点击移动的 WPF 游戏

    我试图将标签网格移动到鼠标的位置 就像冒险游戏中的移动一样 理想情况下 我会在途中删除并重新绘制它们 但是 现在我只想弄清楚如何将 int 转换为厚度或 pointtoscreen 到目前为止我有 player XMove int Mous
  • C# ToString("MM/dd/yy") 删除前导 0 [重复]

    这个问题在这里已经有答案了 可能的重复 格式化 NET DateTime Day 不带前导零 https stackoverflow com questions 988353 format net datetime day with no
  • SSBO 是更大的 UBO?

    我目前正在 OpenGL 4 3 中使用 UBO 进行渲染 以将所有常量数据存储在 GPU 上 诸如材料描述 矩阵等内容 它可以工作 但是 UBO 的小尺寸 我的实现为 64kB 迫使我多次切换缓冲区 减慢渲染速度 我正在寻找类似的方法来存
  • C# - 为什么我需要初始化 [Out] 参数

    我有几个从本机 dll 导入的方法 使用以下语法 internal static class DllClass DllImport Example dll EntryPoint ExampleFunction public static e
  • 在 unix 中编译 dhrystone 时出错

    我是使用基准测试和 makefile 的新手 我已经从下面的链接下载了 Dhrystone 基准测试 我正在尝试编译它 但我遇到了奇怪的错误 我尝试解决它 但没有成功 有人可以帮助我运行 dhrystone 基准测试吗 以下是我尝试编译的两
  • 有没有办法让 VS2010 在我的方法中扩展或收缩 try 块?

    我的代码有很多 try catch finally 块 与我在 VS2010 中的方法不同 除了添加区域之外 我无法在开发时扩展或收缩这些区域来隐藏内容 try vm R vm Qu vm T vm D vm Fil vm Type vm
  • 局部静态变量初始化是线程安全的[重复]

    这个问题在这里已经有答案了 假设我有一个包含三个静态函数的类 如下所示 include
  • ASP.NET Core:会话 ID 始终变化

    今天启动了一个全新的 ASP NET Core 网站 按照说明添加会话 我们在索引页上打印出会话 ID 它始终是唯一的 我认为这可能是 cookie 合规性 所以我在 Chrome 的高级设置和调试器中删除了所有 cookie 但横幅不会再

随机推荐

  • 在 python 中使用 snappy 和 avro 时出现问题

    我正在读取 gz 文件并转换为 AVRO 格式 当我使用codec deflate 它运行良好 即 我能够转换为 avro 格式 当我使用codec snappy 它抛出一个错误 说明如下 raise DataFileException U
  • 如何使用 Python 裁剪通过鼠标单击选择的区域?

    我正在使用 Matplotlib 和 PIL 使用 python 需要查看图像选择并剪切我必须处理的区域 只留下所选区域的图像 我已经知道如何使用 pil 剪切 imagens 使用im crop 但是我如何选择坐标来通过鼠标单击裁剪图像
  • 调试 SSIS 包 - debug.writeline

    SSIS 中的调试体验不是我所期望的 我有一个脚本任务 我添加了一个Imports System Diagnostics在类的标题处 在代码中我有各种 debug writeline 尝试移动文件 类型的消息 但是 它们没有显示在输出窗口中
  • 如何开始测试(jMock)

    我正在尝试学习如何编写测试 我也在学习 Java 有人告诉我应该学习 使用 练习 jMock 我在网上找到了一些在一定程度上有帮助的文章 例如 http www theserverside com news 1365050 Using JM
  • 如何在画布上绘制圆的下半部分

    我正在尝试使用适当的 x cos theta y sin theta 函数绘制圆的下半部分 如果我将 theta 从 Math PI 迭代到 2 Math PI 我似乎得到了圆的上半部分 我在这段代码片段中做错了什么 window onlo
  • 如何使用 jest 和 TypeScript 模拟第三方 Nodejs 模块函数?

    我正在尝试模拟第三方节点模块中的函数 特别是fs readFileSync 功能 使用玩笑 那里有很多示例 但我还没有找到使用 TypeScript 的示例 我有一个简单的 希望是最小的例子 位于github https github co
  • .net 中的 [] 括号是什么? [复制]

    这个问题在这里已经有答案了 我在 C 中很少看到 这样的括号 但是当我开始学习 ASP NET 时 我已经看到它们很多次了 但我仍然无法理解它们的作用 它们不是用于数组的代码的一部分 例如 webmethods 就在方法之上 或者有一些在类
  • Android 10 后台扫描时有限制吗?

    Android 上的蓝牙扫描似乎有很多 隐藏功能 对于初学者来说 有一个 30 秒的限制 Android 7 0 ble扫描没有结果 https stackoverflow com questions 43114913 android 7
  • Python 缩进之谜

    为什么我会收到以下错误 最后print声明不应成为while loop gt gt gt while n gt 0 n n 1 print n print TO A File
  • 从给定的数据集 [纬度、经度、密度] 生成 KML 热图

    我希望构建一个静态 KML Google 地球标记 文件 该文件以 lat lon densis 元组的形式显示一些给定数据集的热图样式渲染 我拥有的一个非常简单的数据集是人口密度 我的要求是 必须能够输入给定纬度 经度的数据 必须能够指定
  • 为什么 solr RemoveDuplicatesTokenFilterFactory 不起作用?

    我的 schema xml 正在拆分产品名称 然后使用RemoveDuplicate 删除拆分后的重复单词
  • graph-tool 需要哪些安装依赖项/选项才能包含draw_hierarchy?

    我已经在 ubuntu 14 04 python 3 5 4 上安装了 graph tool 2 26 我可以使用图形工具 但它似乎不完整 例如我见过这个错误 AttributeError module graph tool draw ha
  • MvcContrib.MVC3-ci 和 Mvc.Contrib NuGet 包之间有什么区别?

    MvcContrib MVC3 ci 和 Mvc Contrib NuGet 包之间有什么区别 我看到它们有不同的依赖项 ci 有更多的下载 我假设我的 MVC3 项目需要 ci 但我如何解决这个问题 ci 是什么意思 据我收集的信息 MV
  • C# 中的三元运算符 (?:) 线程安全吗?

    考虑以下两种获得较大数字的替代方案currentPrice and 100 int price currentPrice gt 100 currentPrice 100 int price Math Max currentPrice 100
  • docker swarm init 无法选择 IP 地址错误

    尝试码头工人群 with 适用于 Mac 的 Docker 桌面 我试过这个 docker machine create d virtualbox node 1 docker machine create d virtualbox node
  • NSString:去掉 并为该段创建带有颜色的属性字符串?

    假设我有一个字符串 这是一个简单的字符串 我需要去掉 抱歉 b 和尖括号之间没有空格 由于某种原因预览没有显示它 同时将 simple 这个词加粗 我的想法是 将尖括号和 br 替换为空白 使 简单 段具有属性 问题是一旦标签被删除 我仍然
  • Eclipse Helios 不显示 Javadoc

    我最近买了一台新计算机 并在其中安装了 Eclipse Helios 之前 在我的旧计算机上 当我使用控制辅助 Ctrl 空格 并突出显示建议的方法时 该方法的 Javadoc 经常出现在控制辅助弹出窗口的一侧 其中包含方法描述和参数等 然
  • 锁定或保护 R 中的 data.table

    是否有一种或多种方法可以锁定或保护data table这样就不能再就地修改了 假设我们有一个 data table dt lt data table id 1 val foo dt id val 1 1 foo 然后我可以修改吗dt之后得到
  • Dockerfile - 中间容器到底在做什么?

    我有我的 Dockerfile 如下所示 FROM confluentinc cp kafka connect 4 0 0 ARG VERSION 0 0 2 15 RUN curl Ls https github com jcustenb
  • 在 C 编译时检查类型是结构体还是指针?

    注意 这是NOTPaul T 链接的问题的重复项 因为我问是否可以在编译时确定类型是否属于某种更广泛的不完整类型 种类 而不是在编译时是否已注册符号 这似乎是对这个问题的根本误解 我正在用 C 编写一个库 该库处理伪通用函数 该函数通过宏包