为什么每个人都对标准C类型进行定义?


103

如果要使用Qt,则必须拥抱quint8quint16依此类推。

如果要使用GLib,则必须欢迎guint8guint16依此类推。

Linux上有u32s16依此类推。

uC / OS定义SINT32UINT16依此类推。

而且,如果您必须结合使用这些东西,则最好为遇到麻烦做好准备。由于你的机器u32将被typedefD,共long并且quint32typedef维超int,编译器会抱怨

如果有的话,为什么每个人都这样做<stdint.h>?这是图书馆的某种传统吗?


8
@Mehrdad在微控制器编程中可以有各种各样的东西。例如,在AVR Mega上(因此在著名的Arduino上),int是16位。这可能是一个令人讨厌的惊喜。我认为“ unsigned short”需要更多的打字工作。这总是让我为<s> byte </ s>八位字节使用'unsigned char'而感到悲伤。未签名的角色,真的吗?
砂仁木

2
@Mehrdad的要点是,您不确定。这就是stdint.h发明的原因。
glglgl

1
@glglgl:这是解决问题的另一种方法:您不是问错了问题吗?如果您要针对多个系统,为什么要先将位数自动硬编码到代码中?即,为什么不只是说sizeof(int) * CHAR_BIT(例如)并使用它呢?如果您的int数据太小而无法表示您的范围(例如数组索引),那么您几乎可以肯定不应该使用int,而是类似的东西size_t。为什么会有int32更多意义呢?固定宽度唯一有意义的时间是系统之间的通信(例如文件/网络格式)...
user541686 '16

1
@Mehrdad否。有时我需要存储值(例如来自ADC或其他任何值)。我知道它们是16位宽。因此,最好使用ting uint16_t(或它的fastleast变体)。我的观点是:这些类型易于使用并且存在它们的原因。
glglgl

1
@Mehrdad:我建议-假设似乎值得您努力产生高质量的代码-您应该定义自己的函数typedef,这意味着与我的API /我的其余代码进行交互的方式,并在技术上根据以下方面进行定义: “技术”类型定义,例如size_t和/或uint64_t
PJTraill '16

Answers:


80

stdint.h在开发这些库时还不存在。因此,每个库都有自己typedef的。


4
好的,我想缺少stdint.h是一个很好的理由,但是为什么今天这些typedef仍然超过int,long等,而不是超过stdint类型?这将使它们至少可以互换
砂仁木

25
@Amomum“为什么Glib(在Linux上开发)未使用Linux typedef?” 尽管glib的“基础”当然是Linux,但从设计上来说,它无疑是一个可移植的库。定义自己的类型可确保可移植性:只需适应一个很小的标头即可将库类型与相应的目标平台类型相匹配。
彼得-恢复莫妮卡

3
@Amomum 为什么使用Glib(在Linux上开发)...不,不是。巧舌如簧的创建方式 Linux内核之前。
andy256 '16

5
@ andy256“ GLib”不是“ glibc”的缩写。这是一个从gtk分支出来的库。它不早于Linux。

2
@ andy256:glib是1998,linux是1991。IOW,GLib是 Linux 之后创建的。
MSalters '16

40

对于较旧的库,这是必需的,因为所涉及的标头(stdint.h)不存在。

但是,仍然存在问题:这些类型(uint64_t和其他类型)是标准中的可选功能。因此,合规的实现可能不随它们一起提供,因此迫使当今的图书馆仍将其包括在内。


14
uintN_t类型是可选的,但uint_leastN_tuint_fastN_t类型都没有。
库桑兰达

7
@Kusalananda:可悲的是,这些工具的作用有限。
Lightness Races in Orbit

16
当然,它们是可选的原因是,你不能保证,有整数类型的正是位数。C仍然支持具有相当奇数整数大小的体系结构。
celtschk

5
@LightnessRacesinOrbit:它们的作用如何有限?我必须承认,除了硬件接口之外,我不明白为什么您需要精确的位数而不是最少的位数来确保所有值都适合
。– celtschk

23
@Amomum 如果实现具有满足要求的类型,需要typedef :“但是,如果实现提供宽度为8、16、32 或64位的整数类型,则没有填充位,并且(对于带符号类型)具有二进制补码表示法,它将定义相应的typedef名称。” (引自N1570,7.20.1.1“精确宽度整数类型”)因此,看来,如果标准库中没有它们,则第三方库也不会。
埃里克·施密特

13

stdint.h 自1999年以来已被标准化。许多应用程序更可能定义(有效地别名)类型,以保持与基础计算机体系结构的部分独立性。

他们使开发人员确信应用程序中使用的类型符合其项目特定的行为假设,这些行为可能与语言标准或编译器实现都不匹配。

这种做法反映在面向对象的Façade设计模式中,并且被开发人员滥用,总是为所有导入的库编写包装器类。

当编译器的标准性大大降低并且机器架构的字长范围从16位,18位36位的大型机不等时,这是一个更重要的考虑因素。在当今使用32位ARM嵌入式系统的世界中,这种做法已不那么重要了。对于具有奇数存储器映射的低端微控制器,仍然值得关注。


1
当然,stdint.h自1999年以来已经标准化,但是实际上已经使用了多长时间?人们为实施和采用新标准而drag之以鼻,在漫长的过渡时期,仍然必须使用旧方法。
任思远

1
一个令人讨厌的陷阱stdint.h是,即使在例如longint32_t具有相同大小和表示形式的平台上,也不需要强制转换int32_t*to long*将产生可以可靠访问a的指针int32_t。我不敢相信标准的作者认为布局兼容的类型应该是别名兼容的很明显,但是由于他们不愿意说,所以gcc和IIRC clang的作者认为,即使忽略别名也可以改善语言。在明显的情况下。
超级猫

2
@supercat-可能值得向C委员会提交勘误表...因为这很愚蠢,请
轻率

@LThode:要让C委员会承认这是一个错误,就必须正式将clang和gcc的行为声明为钝角。您认为这会发生吗?可以期望的最好方法(以及恕我直言,这是继续进行的逻辑方式)将是为程序指定“混叠模式”的方法。如果程序说可以接受非常严格的别名规则,那么编译器可以使用它来允许超出当前可能的优化范围。如果程序指定它要求的规则比当前规则对程序员更友好...
supercat

...但是仍然可以进行许多有用的优化,然后编译器可以生成比使用可能高效得多的代码-fno-strict-alias,但实际上仍然可以运行。即使没有现有的代码库,也没有任何一套规则可以为所有应用程序实现优化和语义的最佳平衡,因为不同的应用程序具有不同的需求。添加现有代码库后,应清楚需要使用不同的模式。
超级猫

3

因此,您可以将type char char转换为int。

一个“编码恐怖”提到一个公司标头指出程序员想要一个布尔值,而char是该工作的逻辑本机类型,因此这样写typedef bool char。然后,后来有人发现整数是最合乎逻辑的选择,并写道typedef bool int。结果实际上是在Unicode之前的时代typedef char int

我认为很多前瞻性,前向兼容性。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.