有什么理由不使用固定宽度的整数类型(例如 uint8_t)? [英] Is there any reason not to use fixed width integer types (e.g. uint8_t)?

查看:27
本文介绍了有什么理由不使用固定宽度的整数类型(例如 uint8_t)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您使用的是支持 C99(甚至只是 stdint.h)的编译器,是否有任何理由不使用 uint8_t 等固定宽度整数类型?

我知道的一个原因是,在处理字符时使用 chars 比使用 (u)int8_ts 更有意义,因为这个问题中提到.

但是如果你打算存储一个数字,你什么时候想使用一个你不知道它有多大的类型呢?IE.在什么情况下,您希望在 unsigned short 中存储一个数字,而不知道它是 8 位、16 位还是 32 位,而不是使用 uint16t?p>

从这里开始,是更好的做法是使用固定宽度的整数,还是使用普通的整数类型,从不假设任何东西,在需要知道多少字节的地方使用 sizeof他们在用吗?

解决方案

实际上存储一个数字而不需要知道类型的确切大小是很常见的.我的程序中有很多数量我可以合理地假设不会超过 20 亿,或者强制它们不超过.但这并不意味着我需要一个精确的 32 位类型来存储它们,任何可以计数到至少 20 亿的类型对我来说都可以.

如果您尝试编写非常便携的代码,您必须记住,固定宽度类型都是可选的.

CHAR_BIT 大于 8 的 C99 实现中,没有 int8_t.该标准禁止它存在,因为它必须具有填充位,并且 intN_t 类型被定义为没有填充位(7.18.1.1/1).uint8_t 因此也被禁止,因为(谢谢,哇)不允许实现在没有 int8_t 的情况下定义 uint8_t.

因此,在非常可移植的代码中,如果您需要一个能够保存最大 127 值的有符号类型,那么您应该使用 signed charintint_least8_tint_fast8_t 根据是否要让编译器制作:

  • 在 C89 中工作(signed charint)
  • 避免在算术表达式中出现令人惊讶的整数提升 (int)
  • 小(int_least8_tsigned char)
  • 快速(int_fast8_tint)

对于高达 255 的无符号类型也是如此,包括 unsigned charunsigned intuint_least8_tuint_fast8_t.

如果您需要在非常便携的代码中进行模 256 运算,那么您可以自己取模、屏蔽位或使用位域玩游戏.

实际上,大多数人从不需要编写可移植的代码.目前 CHAR_BIT >8 仅出现在专用硬件上,您的通用代码不会在其上使用.当然,这在未来可能会改变,但如果发生这种情况,我怀疑有太多代码对 Posix 和/或 Windows 做出假设(两者都保证 CHAR_BIT == 8),处理您的代码的不可移植性将只是将代码移植到该新平台的巨大努力的一小部分.任何这样的实现都可能不得不担心如何连接到互联网(它处理八位字节),早在它担心如何启动和运行你的代码之前:-)

如果您假设 CHAR_BIT == 8 无论如何,那么我认为除了您想要在 C89 中工作的代码.即使在 C89 中,为特定实现找到或编写 stdint.h 版本也不是那么难.但是如果你可以轻松编写你的代码只要求类型可以容纳255,而不是要求它不能容纳256,那么你不妨避免对CHAR_BIT == 8的依赖.

Assuming you're using a compiler that supports C99 (or even just stdint.h), is there any reason not to use fixed-width integer types such as uint8_t?

One reason that I'm aware of is that it makes much more sense to use chars when dealing with characters instead of using (u)int8_ts, as mentioned in this question.

But if you are planning on storing a number, when would you want to use a type that you don't know how big it is? I.e. In what situation would you want to store a number in an unsigned short without knowing if it is 8, 16, or even 32 bits, instead of using a uint16t?

Following on from this, is it considered better practice to use fixed-width integers, or to use the normal integer types and just never assume anything and use sizeof wherever you need to know how many bytes they are using?

解决方案

It's actually quite common to store a number without needing to know the exact size of the type. There are plenty of quantities in my programs that I can reasonably assume won't exceed 2 billion, or enforce that they don't. But that doesn't mean I need an exact 32 bit type to store them, any type that can count to at least 2 billion is fine by me.

If you're trying to write very portable code, you must bear in mind that the fixed-width types are all optional.

On a C99 implementation where CHAR_BIT is greater than 8 there is no int8_t. The standard forbids it to exist because it would have to have padding bits, and intN_t types are defined to have no padding bits (7.18.1.1/1). uint8_t therefore also forbidden because (thanks, ouah) an implementation is not permitted to define uint8_t without int8_t.

So, in very portable code, if you need a signed type capable of holding values up to 127 then you should use one of signed char, int, int_least8_t or int_fast8_t according to whether you want to ask the compiler to make it:

  • work in C89 (signed char or int)
  • avoid surprising integer promotions in arithmetic expressions (int)
  • small (int_least8_t or signed char)
  • fast (int_fast8_t or int)

The same goes for an unsigned type up to 255, with unsigned char, unsigned int, uint_least8_t and uint_fast8_t.

If you need modulo-256 arithmetic in very portable code, then you can either take the modulus yourself, mask bits, or play games with bitfields.

In practice, most people never need to write code that portable. At the moment CHAR_BIT > 8 only comes up on special-purpose hardware, and your general-purpose code won't get used on it. Of course that could change in future, but if it does I suspect that there is so much code that makes assumptions about Posix and/or Windows (both of which guarantee CHAR_BIT == 8), that dealing with your code's non-portability will be one small part of a big effort to port code to that new platform. Any such implementation is probably going to have to worry about how to connect to the internet (which deals in octets), long before it worries how to get your code up and running :-)

If you're assuming that CHAR_BIT == 8 anyway then I don't think there's any particular reason to avoid (u)int8_t other than if you want the code to work in C89. Even in C89 it's not that difficult to find or write a version of stdint.h for a particular implementation. But if you can easily write your code to only require that the type can hold 255, rather than requiring that it can't hold 256, then you might as well avoid the dependency on CHAR_BIT == 8.

这篇关于有什么理由不使用固定宽度的整数类型(例如 uint8_t)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆