我的代码中有以下类型定义:
#define FOO_OFF 0
#define FOO_ON 1
typedef uint8_t foo;
#define BAR_NO 0
#define BAR_YES 1
#define BAR_UNKNOWN 255
typedef uint8_t bar;
这两种类型虽然具有相同的基础类型,但它们携带的信息不同。
实际上,如果代码中的任何人执行以下操作,我希望得到警告:
foo foovar = FOO_OFF;
void get_bar(bar *outvar)
{
// assigning the bar variable a foo variable content
*outvar = foovar;
}
我在gcc中找不到任何这样的警告选项,我遇到了accross -Wconversion
,但只有在有可能丢失信息的情况下才会发出警告,而在我的示例中并非如此。
有人知道我能做些什么吗?显然,当真正需要类型更改时,应该可以进行强制转换。
3条答案
按热度按时间sxissh061#
简短的回答是否定的,您不能这样做。
typedef
声明了一个别名,而不是一个新类型,因此任何遵守该标准的编译器都不能拥有您现在想要的特性。不过,您可以借由引入新型别、使用枚举或结构来达成。
如果您使用C语言,则可以轻松地从一个枚举转换到另一个枚举。
因为struct的第一个元素的地址也是struct的地址,所以你可以通过转换struct地址,然后用它的新类型取消引用指针,从而在int8或另一个struct之间转换它。(
*((dest_type *)&value)
)vptzau2j2#
我非常喜欢问题Strongly typed using and typedef的作者所在团队提出的解决方案,因为它非常简单:
不幸的是,它不能处理原始类型,但它与
BOOST_STRONG_TYPEDEF
类似,可以。下面是一个小例子和两者的退化“比较”:
mbjcgjjk3#
如果大小不一定是一个字节,我们可以(ab)使用指针:
预处理器符号不再是常量表达式,我们不能把它们用作开关标签之类的东西。
一个很好的解决方案是使用C类型安全的
enums
。这是用“干净的C”编写代码的优点之一:一种非正式的名称,指在一种语言方言中工作,它编译成某种版本的C,以及具有相同行为的某种版本的C。简单地说:
在C中,您仍然可以将
ROLLOVERDETECTED_YES
赋给rolloverdetection
类型的变量,但在C中就不行了。如果将代码编译为C,则可以使用C编译器检查这些冲突,即使代码的发布版本不使用C。
如果以8位存储值很重要,我记得GCC支持枚举类型的位域作为扩展(ISO C中没有):
C++枚举不是完全类型安全的;从
enum
成员到整数类型的隐式转换是可能的:而不是在相反方向上。
顺便说一句,如果你用C和C++编译,其他的技术也会出现,比如能够使用更细微的类型转换:
所以现在,举例来说,我们可以
在C语言中,这只是一个不安全的
(char *) str
类型转换。在C中,上述宏会产生const_cast<char *>(str)
。因此,如果str
一开始是const char *
,但后来有人将其更改为const wchar_t *
,C编译器将诊断上述类型转换。然而,我们的项目并不 * 需要 * C编译器来构建。与此同时,如果您使用GCC,其C前端具有
-Wold-style-cast
,它将查找代码中使用(type) value
转换标记法的所有位置。