C 宏 _Generic 给出意外的编译器错误

2023-11-24

使用 gcc.exe(Rev3,由 MSYS2 项目构建)8.2.0。

我试图构建一个宏来自动在两种类型之间进行类型转换,其中两个参数永远不应该是相同的类型。我的问题是,如果我不包含相同类型的情况,编译器会抛出错误。 我想要什么:

#include <stdio.h>
#include <stdint.h>
// Macro to return string based on two different types
#define bob( to, from ) \
    _Generic( to , \
    int32_t: _Generic(from,  \
      int16_t: "s-l", \
      int8_t:  "c-l" ) , \
    int16_t: _Generic(from, \
      int32_t: "l-s", \
      int8_t:  "c-s") , \
    int8_t:_Generic(from, \
      int32_t: "l-c",  \
      int16_t: "s-c")  \
    )

    void main(void)
    {
        int32_t i1;
        int16_t s1;
        int8_t  c1;

        printf("%s\n", bob(i1,s1));
        printf("%s\n", bob(i1,c1));
        printf("%s\n", bob(s1,c1));
        printf("%s\n", bob(s1,i1));
        printf("%s\n", bob(c1,s1));
        printf("%s\n", bob(c1,s1));

    }

$ gcc gbug.c -o gbug.exe
gbug.c: In function 'main':
gbug.c:23:27: error: '_Generic' selector of type 'short int' is not compatible with any association
     printf("%s\n", bob(i1,s1));
                           ^~
gbug.c:9:19: note: in definition of macro 'bob'
 int16_t: _Generic(from, \
                   ^~~~
gbug.c:24:27: error: '_Generic' selector of type 'signed char' is not compatible with any association
     printf("%s\n", bob(i1,c1));
                           ^~
gbug.c:12:17: note: in definition of macro 'bob'
 int8_t:_Generic(from, \
                 ^~~~
gbug.c:25:27: error: '_Generic' selector of type 'signed char' is not compatible with any association
     printf("%s\n", bob(s1,c1));
                           ^~
gbug.c:12:17: note: in definition of macro 'bob'
 int8_t:_Generic(from, \
                 ^~~~
gbug.c:26:27: error: '_Generic' selector of type 'int' is not compatible with any association
     printf("%s\n", bob(s1,i1));
                           ^~
gbug.c:6:19: note: in definition of macro 'bob'
 int32_t: _Generic(from,  \
                   ^~~~
gbug.c:27:27: error: '_Generic' selector of type 'short int' is not compatible with any association
     printf("%s\n", bob(c1,s1));
                           ^~
gbug.c:9:19: note: in definition of macro 'bob'
 int16_t: _Generic(from, \
                   ^~~~
gbug.c:28:27: error: '_Generic' selector of type 'short int' is not compatible with any association
     printf("%s\n", bob(c1,s1));
                           ^~
gbug.c:9:19: note: in definition of macro 'bob'
 int16_t: _Generic(from, \

这个例子是我发现的最简单的例子,但会失败。

如果我添加“相同类型”转换行,如下所示:

#define bob( to, from ) \
_Generic( to , \
int32_t: _Generic(from,  \
  int16_t: "s-l", \
  int32_t: "bug", \
  int8_t: "c-l" ) , \
int16_t: _Generic(from, \
  int32_t: "l-s", \
  int16_t: "bug", \
  int8_t: "c-s") , \
int8_t:_Generic(from, \
  int32_t: "l-c",  \
  int8_t: "bug", \
  int16_t: "s-c")  \
)

它构建并运行并达到预期结果:

$ ./gbug.exe
s-l
c-l
c-s
l-s
s-c
s-c

验证我没有使用宏来扩展任何相同类型的条件。 我知道 _Generic 不是字符串替换宏,但我也认为,如果您可以在没有默认情况下使用它,那么如果您使用未知类型(或不受支持的类型组合,这是我想要的行为),它会正确抛出编译错误) 这就像预处理器将两个宏参数混合在一起。

编辑:所以我有了更好的理解,(请参阅下面的答案),但仍然希望在两个参数类型相同时让宏抛出编译错误。到目前为止,我有一个技巧来强制出现链接错误,这仍然比运行时错误更好。


问题是通用选择的每个分支都必须有效,即使它们没有被评估。

例如,您的第一个宏:

bob(i1, s1)

扩展为(为了清楚起见添加的类型):

_Generic( ((int32_t) i1),
  int32_t: _Generic( ((int16_t) s1),
    int16_t: "s-l",
    int8_t:  "c-l" ),
  int16_t: _Generic( ((int16_t) s1),  // The error is here
    int32_t: "l-s",
    int8_t:  "c-s"),
  int8_t:_Generic( ((int16_t) s1),
    int32_t: "l-c",
    int16_t: "s-c")
)

显然uint32_t分支有效:它只是选择"s-l"。但是int16_t分支是not有效,如from (An int16_t本身)没有相应的分支。

在这种特殊情况下,添加一个不执行任何操作的自转换运算符不会有什么坏处。

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

C 宏 _Generic 给出意外的编译器错误 的相关文章

  • 命名管道客户端无法连接到作为网络服务运行的服务器

    我有一个服务在网络服务帐户下运行 该服务只是设置一个命名管道并侦听连接 NamedPipeServerStream listeningPipe new NamedPipeServerStream ourservicepipe PipeDir
  • C语言实现延时函数

    我想使用空循环实现延迟函数 但是完成一次循环所需的时间取决于编译器和机器 我希望我的程序自行确定时间并将程序延迟指定的时间 谁能给我任何想法如何做到这一点 注意 有一个名为delay 的函数可以将系统暂停指定的毫秒 是否可以在不使用此功能的
  • 为什么 fgets 接受 int 而不是 size_t?

    功能如strcpy malloc strlen 和其他各种接受他们的参数或返回值作为size t代替int or an unsigned int出于显而易见的原因 一些文件功能 例如fread and fwrite use size t以及
  • 带有嵌入 Flash 视频的 PDF 示例?

    有谁知道我在哪里可以查看嵌入 Flash 视频的 PDF 示例 我知道问这个问题很愚蠢 因为你会认为任何面向技术的用户都应该能够使用谷歌找到一个 但我真的找不到 我的另一个问题是 使用 C 中的 API 将 Flash 视频嵌入 PDF 文
  • C 链表销毁函数

    我正在尝试学习 C 和很多人一样 我对指针有点困惑 无论如何 我创建了一个递归函数来销毁我的链表 但是正如我调试的那样 当我从函数返回时 列表的头部不应该为空 所以我猜这是对指针的一些基本误解 这是函数 void destroy struc
  • 为什么 ObservableCollection 有两个集合构造函数?

    The 可观察集合 T https msdn microsoft com en us library ms668604类有两个构造函数 可以在其中传递项目集合 一个构造函数接受一个IEnumerable T 另一个List T 鉴于List
  • 有没有办法找到dll公开的所有函数

    我一直在寻找一种方法来获取映射到 dll 中函数名称的所有字符串 我的意思是您可以调用 GetProcAddress 的所有字符串 如果你对 dll 进行十六进制转储 符号 字符串 就在那里 但我认为必须有一个系统调用来获取这些名称 如果您
  • Web浏览器控件:如何捕获文档事件?

    我正在使用 WPF 的 WebBrowser 控件加载一个简单的网页 在这个页面上我有一个锚点或一个按钮 我想在我的应用程序后面的代码中 即在 C 中 捕获该按钮的单击事件 WebBrowser 控件是否有办法捕获加载页面元素上的单击事件
  • 编译器消息“警告:格式‘%s’需要类型‘char *’,但参数 2 具有类型‘char (*)’”

    我正在尝试运行一个简单的 C 程序 但收到此错误 警告 格式 s 需要类型 char 但参数 2 的类型为 char 20 我在跑步Mac OS X v10 8 https en wikipedia org wiki OS X Mounta
  • 如何解析多态 JSON 数组?

    我有一个 JSON 格式的文件 其中包含个人用户的记录 一些用户的记录中间有一个评论字段 我只想解析顶级项目 全名 贡献者姓名 电子邮件 使用 Newtonsoft JSON 解析器 但我似乎无法让它识别单个对象 当我将整个字符串解析为一个
  • 将旧的 Unity 代码升级到 Unity 5

    在触发按钮上播放动画的代码似乎不起作用 我在 Youtube 上看到了一个视频 内容很简单animation Play 它可以在该视频上运行 但我无法让它在我的计算机上运行 我做错了什么还是团结改变了它 请帮助我在网上找不到解决方案 所有
  • 为什么最小的 int -2147483648 的类型为“long”? [复制]

    这个问题在这里已经有答案了 对于一个学校项目 我必须编写 C 函数 printf 的代码 一切进展顺利 但有一个问题我找不到好的答案 所以我来了 printf PRINTF d t d n 2147483648 告诉我 gcc Werror
  • “DeploymentItem”属性是什么意思?

    假设我们有一个简短的程序 namespace ConsoleTryIt static class Program static void Main string args var sum Add 1 2 private static int
  • 如何将 Boost Spirit 自动规则与 AST 结合使用?

    编辑 当我想在另一个规则上使用它时 我扩展了 sehe 的示例以显示问题 http liveworkspace org code 22lxL7 http liveworkspace org code 22lxL7 17 我正在尝试提高 Bo
  • C中使用JNI从对象获取对象

    public class Student private People people private Result result private int amount 这是 Java 中类的示例 在C中 我试图获取 学生 中的 人 但失败了
  • NSubstitute - 测试特定的 linq 表达式

    我在当前正在开发的 MVC 3 应用程序中使用存储库模式 我的存储库界面如下所示 public interface IRepository
  • 在链表程序中使用模板时重载 C++ 中的 << 运算符

    我正在尝试实现一个链接列表 但是当我尝试重载 include
  • 为什么我无法通过 lambda 捕获“this”指针?

    考虑以下代码 class A public void foo auto functor this A a this auto functor a The compiler won t accept this instead of a a g
  • 打印任何类型的数组和列表的通用方法[重复]

    这个问题在这里已经有答案了 每当我调试一段涉及整数 双精度 字符串等数组或列表的代码时 有时我更喜欢打印它们 我为此所做的是为不同类型编写重载的 printArray printList 方法 for e g 我可能有这 3 种方法来打印各
  • DbContext.SaveChangesAsync 异常处理

    当搭建新的脚手架时ApiController通过 Visual Studio 2013 中的异步操作和实体框架支持 某些方法可以包装DbContext SaveChangesAsync https msdn microsoft com en

随机推荐

  • HTML5 向后兼容 XHTML 吗?

    简短的问题 我可以将现有 XHTML 1 0 网站的 DOCTYPE 更改为 HTML5 吗 这会导致任何问题吗 很长的故事 我们有一个用 ASP NET Webforms 编写的网站 由于它相当旧 默认的 DOCTYPE 设置为 XHTM
  • 使用他的 ClassType 来转换 TObject?

    我怎样才能让我的代码工作 我试图提出这个问题 但经过几次失败的尝试后 我认为你们通过查看代码会比阅读我的 解释 更快地发现问题 谢谢 setCtrlState memo1 edit1 button1 False procedure setC
  • 带参数的 Django 重定向()

    已经有人问过几个类似的问题 但在花了很长时间后我找不到问题的答案 在下面的代码中 当我使用参数 username 从 myView 重定向到 anotherView 时 它按预期工作正常 但我也需要在此重定向中包含 范围 参数 因为重定向后
  • Android 中强制通过扬声器输出声音

    Android 有没有办法强制通过手机扬声器输出 即使耳机已插入插孔 我知道必须有一种方法 因为当您打电话时 即使插孔中插入了耳机 您也可以让某人使用免提电话 您可以使用以下命令在系统范围内更改此设置AudioManager setSpea
  • oo问题-混合控制器逻辑和业务逻辑

    我不确定我是否使用 标准 术语 但这是我试图解决的一个基本的面向对象问题 我正在编写一个 Windows 窗体 我不需要表单事件处理程序中的逻辑 因此我只需从那里调用自定义对象 在自定义对象中 有两组逻辑 控制器 逻辑 决定需要完成什么以及
  • 编译器生成的默认构造函数会是公共的吗?

    当我写一个类的时候Widget java public class Widget int data String name 编译器生成的构造函数是public or default 公众会像 public class Widget int
  • HTML 中的方括号形成数组。只是传统的还是有意义的?

    我经常看到 特别是在 PHP 世界中 如果你想创建一个 FORM 数组 可以这样写
  • 如何将 Firebase 身份验证令牌传递给 webView 并在 Android 上注册通知

    我有一个 Firebase WebApp 它向用户提供信息 除了应用程序之外 我还需要通过 Firebase 云消息传递向使用 Android 应用程序的用户发送推送通知 目标 用户应该一次登录到应用程序 既可以注册通知 又可以通过 Web
  • Google 时间轴图表持续时间(以小时为单位)

    我正在使用 Google 时间线图表 即使持续时间超过一天 我也想以小时为单位显示持续时间 是否可以 谢谢 包含一千个样本的图像 展示了不同的行为1正如您所看到的 红色的持续时间是错误的 蓝色的持续时间是计算和打印的 没有配置选项更改工具提
  • 在哪里可以找到当前的 C 或 C++ 标准文档?

    这个问题的答案是社区努力 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 对于许多问题 答案似乎可以在 标准 中找到 然而 我们在哪里可以找到它呢 最好是在线 谷歌搜索有时会让人感到徒劳 尤其是对于 C 标准 因为它们淹没在编程论坛上
  • C 中的外部指针和静态指针

    您好 静态和外部指针的用法是什么 如果它们存在的话 为了回答您关于何时可以使用它们的问题 举几个简单的例子 静态指针可用于实现始终向程序返回相同缓冲区的函数 并在第一次调用时分配它 char GetBuffer static char bu
  • Java错误:应该在名为[重复]的文件中声明

    这个问题在这里已经有答案了 我对 Java 相当陌生 并试图弄清楚如何解决以下错误 读取错误 CalculatorWithMemory java 1 class Calculator is public should be declared
  • 如何找到最近的标记 leaflet.js

    我想知道是否真的有某种方法可以使用 leaflet js 找到我位置附近的标记 我首先想到的是存储我所在位置的纬度和经度 然后迭代一系列纬度和经度标记 将它们放入一个数组中 然后对该数组进行排序 我不确定这是否是一个好的选择 因为如果地图上
  • 路由器在 NAT 中保留记录多长时间?这些记录可以重复使用来转发来自其他主机的请求吗?

    有一个答案以简单的方式解释了路由器如何将请求从本地网络转换到外部网络并返回 https superuser com questions 105838 how does router know where to forward packet
  • 在 winapi 中拖放

    我有一个纯 Winapi 应用程序 需要一些新功能 其中之一最好实现为两个列表 您可以在列表之间拖放 多个 元素 新功能可以仅限于单个对话框 实现这一点的最快方法是什么 一些想法 纯Winapi 是DetectDrag 提供这一对话框的单独
  • Gradle resValue 导致重复字符串资源

    我的 Android 清单文件定义应用程序名称如下 android label string app name res values strings xml 中存在 app name 的相应条目 现在 在我的 build gradle 中
  • 如何使 Python/Sphinx 文档对象属性仅在 __init__ 中声明?

    我有带有对象属性的 Python 类 这些属性仅在运行构造函数时声明 如下所示 class Foo object def init self base self basepath base temp for run in os listdi
  • 从 C# 中的枚举获取字符串名称

    我已经声明了一个枚举 如下所示 public enum State KARNATAKA 1 GUJRAT 2 ASSAM 3 MAHARASHTRA 4 GOA 5 从外部来源 我得到的状态值为 1 或 2 或 3 或 4 或 5 根据我得
  • 是什么让 C 比 Python 更快? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 我知道这可能是一个非常明显
  • C 宏 _Generic 给出意外的编译器错误

    使用 gcc exe Rev3 由 MSYS2 项目构建 8 2 0 我试图构建一个宏来自动在两种类型之间进行类型转换 其中两个参数永远不应该是相同的类型 我的问题是 如果我不包含相同类型的情况 编译器会抛出错误 我想要什么 include