Dan*_*bbs 48 c byte integer sizeof c99
假设您使用的是支持C99(甚至只是stdint.h)的编译器,是否有任何理由不使用固定宽度整数类型,如uint8_t?
我所知道的一个原因是,char在处理字符而不是使用s时使用s 更有意义(u)int8_t,如本问题所述.
但是如果你打算存储一个数字,你何时想要使用一种你不知道它有多大的类型?即在什么情况下你想要在unsigned short不知道它是8,16甚至32位的情况下存储一个数字,而不是使用uint16t?
接下来,使用固定宽度整数或使用普通整数类型并且从不假设任何东西并且使用sizeof它们需要知道它们使用了多少字节时,它被认为是更好的做法吗?
Ste*_*sop 37
实际上存储一个数字而不需要知道该类型的确切大小是很常见的.在我的程序中有足够的数量,我可以合理地假设不会超过20亿,或强制他们没有.但这并不意味着我需要一个精确的32位类型来存储它们,任何可以计入至少20亿的类型对我来说都很好.
如果您正在尝试编写非常便携的代码,则必须记住固定宽度类型都是可选的.
在C99实现中,CHAR_BIT大于8没有int8_t.标准禁止它存在,因为它必须有填充位,并且intN_t类型被定义为没有填充位(7.18.1.1/1).uint8_t因此也禁止因为(感谢,ouah)的实现是不允许来定义uint8_t,而不int8_t.
因此,在非常便携的代码,如果你需要能容纳值高达127签署的类型,那么你应该使用一个signed char,int,int_least8_t或者int_fast8_t根据您是否要问编译器,使其:
signed char或int)工作int)中令人惊讶的整数提升int_least8_t或signed char)int_fast8_t或int)这同样适用于无符号类型多达255个,其中unsigned char,unsigned int,uint_least8_t和uint_fast8_t.
如果你需要在非常便携的代码中进行模256运算,那么你可以自己采用模数,屏蔽位,或者用位域玩游戏.
在实践中,大多数人从不需要编写便携式代码.目前CHAR_BIT > 8只出现在专用硬件上,您的通用代码将不会被使用.当然,这可能会在未来发生变化,但如果确实如此,我怀疑有太多的代码可以对Posix和/或Windows进行假设(两者都保证CHAR_BIT == 8),处理代码的不可移植性将只是其中的一小部分.将代码移植到新平台的巨大努力.任何这样的实现可能不得不担心如何连接到互联网(处理八位字节),早在它担心如何启动和运行代码之前:-)
如果你还是假设CHAR_BIT == 8那么我认为没有任何特别的理由可以避免(u)int8_t,除非你想让代码在C89中工作.即使在C89中,找到或编写stdint.h特定实现的版本并不困难.但是如果你可以轻松地编写你的代码只需要类型可以保持255,而不是要求它不能保持256,那么你也可以避免依赖CHAR_BIT == 8.
sup*_*cat 12
还没有被提及的一个问题是,虽然使用固定大小的整数类型的将意味着,如果编译器使用不同大小的一个的变量的大小不会改变int,long等,它不一定会保证即使定义了大小,该代码在具有各种整数大小的计算机上的行为也相同.
例如,给定声明uint32_t i;,表达式为零(i-1) > 5时的行为i将根据a uint32_t是否小于而变化int.在例如int64位(并且uint32_t类似long short)的系统上,变量i将被提升为int; 减法和比较将以有符号的形式执行(-1小于5).在int32位的系统上,减法和比较将被执行为unsigned int(减法将产生一个非常大的数,大于5).
我不知道有多少代码依赖于这样一个事实,即即使在没有类型转换的情况下,包含无符号类型的表达式的中间结果也需要包装(恕我直言,如果需要包装行为,程序员应该包含类型转换) (uint32_t)(i-1) > 5)但是标准目前不允许有余地.我想知道如果一条规则至少允许编译器在没有类型转换或类型强制的情况下将操作数提升为更长的整数类型的规则[例如,给定的uint32_t i,j,就像j = (i+=1) >> 1;需要那样的赋值来切断溢出,那么会产生什么问题)j = (uint32_t)(i+1) >> 1;但是j = (i+1)>>1不会]?或者,就此而言,编译器制造商要保证其中间结果可能都符合最大签名类型并且不涉及非恒定量的右移的任何整数类型表达式将会产生相同的难度.结果好像所有计算都是在那种类型上进行的?在int32位的机器上,我觉得相当icky :
uint64_t a,b,c; ... a &= ~0x40000000; b &= ~0x80000000; c &= ~0x100000000;
清除每一个比特a和c,但清除的顶部33比特b; 大多数编译器都不会暗示任何关于第二个表达式的"不同".
确实,标准整数类型的宽度可能会从一个平台变为另一个平台而不是其最小宽度.
例如,C标准规定a int至少为16-bita且a long至少为32-bit宽.
如果在存储对象时没有一些大小限制,可以将其用于实现.例如,如果您的最大签名值适合16-bit您,您可以使用int.然后,让实现最终int确定实现所针对的体系结构的自然宽度.
| 归档时间: |
|
| 查看次数: |
11526 次 |
| 最近记录: |