转换为相同大小的无符号类型

转换为相同大小的无符号类型

介绍

在cdecl中,有这样的枚举:

enum cdecl_show {  cdecl_show_predefined       = 1 << 0,  cdecl_show_user_defined     = 1 << 1,  cdecl_show_opt_ignore_lang  = 1 << 2};typedef enum cdecl_show cdecl_show_t;

其值是可以按位或在一起的位标志。

标志的作用在这里并不重要,但是,简单地说,它们控制响应 cdecl show 命令而显示哪些类型。

我正在努力增强 show 命令的行为,以便如果没有显示具有特定名称的用户定义类型,则通过以下代码显示具有相同名称的预定义类型(如果有):

if ( !showed_any && (show & cdecl_show_user_defined) != 0 ) {  show &= ~cdecl_show_user_defined;  show |= cdecl_show_predefined;  // ...}

即关闭cdecl_show_user_defined 位并打开cdecl_show_predefined 位。 问题是,当使用符号转换编译器选项进行编译时,我得到:

show.c:244:8: warning: implicit conversion changes signedness: 'int' to 'unsigned int' [-wsign-conversion]  show &= ~cdecl_show_user_defined;       ~~ ^~~~~~~~~~~~~~~~~~~~~~~~1 warning generated.

发生这种情况是因为 c 中的枚举值隐式转换为其基础类型(此处为 int),但 ~ 将其操作数转换为无符号 int。

消除警告的明显方法是首先转换为 unsigned:

  show &= ~(unsigned)cdecl_show_user_defined;  // no warning

问题是,在 c23 之前的 c 语言中,你无法确定枚举的底层类型是什么。 来自 c11 标准 §6.7.2.2 ¶4:

每个枚举类型应与 char、有符号整数类型或无符号整数类型兼容。类型的选择是实现定义的。

如果您不知道基础类型是什么,特别是它的大小,您就不知道 unsigned int 是无符号类型的正确选择,因为您希望大小匹配。

鉴于 cdecl_show 只有值 1、2 和 4,可以肯定它的基础类型是 int — 但你不能确定。 我们需要的是一种转换为与给定表达式的类型大小相同的无符号类型的方法。

解决方案

使用 _generic 和 static_if (在那篇文章中给出),我们可以实现:

#define to_unsigned(n)                      static_if( sizeof(n) == sizeof(char),       (unsigned char)(n),                     static_if( sizeof(n) == sizeof(short),      (unsigned short)(n),                    static_if( sizeof(n) == sizeof(int),        (unsigned int)(n),                      static_if( sizeof(n) == sizeof(long),       (unsigned long)(n),                       (unsigned long long)(n) ) ) ) )

其中 n 是任何整数或枚举类型的任何数值表达式。 实现很简单:使用 static_if 链来确定表达式 n 的类型的大小,然后将其转换为相同大小的无符号类型。

鉴于此,我现在可以写:

  show &= ~TO_UNSIGNED( CDECL_SHOW_USER_DEFINED );

并且没有任何警告。

结论

再次,_generic 允许您进行一些编译时类型自省。 to_unsigned() 的好处是,即使底层类型发生变化,它也始终有效。

除了对枚举有用之外,它对于整型类型的 typedef 也很有用,因为你永远不必查找 typedef 的基础类型来知道要转换为哪个无符号类型。

以上就是转换为相同大小的无符号类型的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1455549.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月18日 07:51:58
下一篇 2025年12月18日 07:52:07

相关推荐

发表回复

登录后才能评论
关注微信