C “long”保证和“size\t”一样宽吗`
在寻找C “long”保证和“size\t”一样宽吗`,c,language-lawyer,c89,C,Language Lawyer,C89,在寻找unsigned long足以容纳size\u t作为printf参数的证据时,我遇到了两个事实(oid) 首先,这说明long确实不能保证足够大以容纳size\u t。另一方面,我看到这建议在C99之前使用printf(“%lu”,(无符号长)x),x为size\u t 因此,问题是您是否可以假设或保证long足够容纳size\u t在C99之前的中。另一个问题是,是否存在任何保证size\u t可以适用于任何其他标准化整数类型(除了明显的例外,如ssize\u t、ptrdiff\u
unsigned long
足以容纳size\u t
作为printf
参数的证据时,我遇到了两个事实(oid)
首先,这说明long
确实不能保证足够大以容纳size\u t
。另一方面,我看到这建议在C99之前使用printf(“%lu”,(无符号长)x)
,x
为size\u t
因此,问题是您是否可以假设或保证
long
足够容纳size\u t
在C99之前的中。另一个问题是,是否存在任何保证size\u t
可以适用于任何其他标准化整数类型(除了明显的例外,如ssize\u t
、ptrdiff\u t
等)。没有这种保证
虽然对于实现来说,long
和size\u t
具有相同的大小是常见的,但情况并非总是如此。如注释所示,Windows 64位的long
和size\u t
大小不同
还请注意,实现的SIZE_MAX
的最小值为65535
,而ULONG_MAX
的最小值为4294967295
(2147483647
用于LONG_MAX
)。(请注意,SIZE\u MAX
与C99一起出现。)这意味着SIZE\u t
保证至少为16位,但无符号长
/长
保证至少为32位
编辑:在回答这个问题后,问题有了一些变化。。。因此:
因此,问题是,您是否可以假设或保证,在C99之前,足够长的时间来保持尺寸
即使在C89中也没有此类保证long
可以是32位和size\u t
64位。(请参见上面64位Windows中带有MSVC的C89示例。)
另一个问题是,是否有任何保证可以保证size_t适合任何其他标准化整数类型(除了明显的例外,如ssize_t、ptrdiff_t等)
同样,标准也没有这样的保证size\u t
是另一个标准无符号整数类型的别名(它不能是扩展整数类型,因为C89没有扩展整数类型)
因此,问题是您是否可以假设或保证long
足够容纳size\u t
在C99之前的中
不是long
,而是无符号long
在C89/C90中,size\u t
必须是无符号整数类型。C89/C90中正好有4种无符号整数类型:无符号字符
,无符号短
,无符号整数
,和无符号长
。因此,在C89/C90中,size\u t
的宽度不能大于unsigned long
,因此size\u t
类型的任何值都可以转换为unsigned long
,而不会丢失信息。(这仅适用于无符号长
,不适用于长
)
随着无符号long-long
和扩展整数类型的引入,这种隐式保证在C99中消失了。在C99及更高版本中,大小\u t
可以比无符号长
宽。例如,C99实现可能具有32位long
和64位long
,并使size\u t
成为无符号long
的别名
即使在C89/C90中,您也只能在具有符合要求的C89/C90实现的情况下才能依赖担保。C99之前的编译器通常在C89/C90标准之上提供扩展——例如,编译器可能支持long-long
,并且可能使size\u t
成为unsigned-long
的别名,即使编译器不完全支持C99(或C11)标准
问题是关于printf
。请记住,printf
的参数必须是格式字符串的适当类型。这:
printf("sizeof (int) = %lu\n", sizeof (int));
具有未定义的行为,除非size\u t
恰好是unsigned long
的别名(即使size\u t
和unsigned long
恰好具有相同的大小)。您需要将值强制转换为正确的类型:
printf("sizeof (int) = %lu\n", (unsigned long)sizeof (int));
对于C99及更高版本,您可以直接打印size\t
值:
printf("sizeof (int) = %zu\n", sizeof (int));
如果愿意,您可以测试\uuuu STDC\u VERSION\uuuu
的值,以确定使用哪一个
(关于C标准版本的说明。第一个C标准于1989年由ANSI发布。1990年由ISO重新发布,并添加了额外的样板章节。因此C89和C90是描述同一语言的两个不同文件。后来的C99和C11标准由ISO发布。所有三个ISO C标准均由ISO正式采用。)所以严格地说,“ANSIC”应该是指ISO C11——但由于历史原因,这个短语仍然用于指1989年的标准。)同样,64位windows具有32位长和64位大小。\u tAlso:
size\u t
未签名,long
s已签名。对于windows和Visual Studio,用于打印大小变量的格式说明符为(%大写I)%I后面可选地跟o、u、x或x,它们将在32位和64位模式下工作。对于GCC,我认为它是%zu(不确定是否可以将其他后缀与%z一起使用)。不幸的是,这个答案似乎被过早地发布了(正如问题所示),这个问题后来完成了,所以这并不能真正回答问题。@skyking-在Visual Studio(2013年及更高版本,可能也是2015年)的情况下,它的C(不是C++)编译器是在C99之前的。