简体   繁体   English

我可以信任sizeof(size_t)<= sizeof(unsigned long int)总是如此吗?

[英]Can I trust sizeof(size_t) <= sizeof(unsigned long int) is always true?

Can I trust sizeof(size_t) <= sizeof(unsigned long int) is always true, according to C89 standard? 根据C89标准,我可以信任sizeof(size_t) <= sizeof(unsigned long int)总是如此吗?

ie, I will not loos value if I use a unsigned long where size_t is expected and vice-versa. 也就是说,如果我使用unsigned long ,而不是size_t ,反之亦然,我就不会放松。

Perhaps the best explanation of what happens with size_t and integer types in C89 is the rationale document of it. 也许对C89中 size_t和整数类型所发生的事情的最好解释是它的基本原理。 Read carefully the section 3.4.4 of this document: 请仔细阅读本文档的第3.4.4节:

Sizeof and size_t for C89 (rationale) C89的sizeof和size_t(理由)

The 3rd paragraph says that: 第3段说:

The type of sizeof, whatever it is, is published (in the library header ) as size_t, since it is useful for the programmer to be able to refer to this type. sizeof的类型,无论它是什么,都以size_t的形式发布(在库头中),因为程序员能够引用这种类型是有用的。 This requirement implicitly restricts size_t to be a synonym for an existing unsigned integer type, thus quashing any notion that the largest declarable object might be too big to span even with an unsigned long. 此要求隐式地将size_t限制为现有无符号整数类型的同义词,从而消除了即使使用无符号长整数,最大可声明对象可能太大而无法跨越的任何概念。

This means that, for the concern of C89 , in general size_t is the same as a preexisting unsigned integer type, what in C89 implies one of the unsigned char, unsigned short, unsigned int, unsigned long . 这意味着,对于C89的关注,通常size_t与预先存在的unsigned整数类型相同,C89中的含义是unsigned char, unsigned short, unsigned int, unsigned long
In particular, every value of type size_t is in the range of unsigned long . 特别是, size_t类型的每个值都在unsigned long的范围内。
By reading the specifications of the standard C89, you can see also that sizeof(size_t)<=sizeof(long) . 通过阅读标准C89的规格,您还可以看到sizeof(size_t)<=sizeof(long)


Now, the situation in C99 is a little different. 现在, C99的情况有点不同。 This standard says that: 该标准说:

  1. 7.17 par. 7.17标准杆 2 size_t is an unsigned integer type. 2 size_t是无符号整数类型。
  2. 7.17 par. 7.17标准杆 4 The types used for size_t [...] should not have an integer conversion rank greater than that of signed long int 4用于size_t [...]的类型的整数转换等级不应大于signed long int的整数转换等级
  3. --------- unless the implementation supports objects large enough to make this necessary. ---------除非实现支持足够大的对象以使其成为必要。
  4. 6.2.5 par. 6.2.5标准杆 8 For any two integer types with the same signedness and different integer conversion rank (see 6.3.1.1), the range of values of the type with smaller integer conversion rank is a subrange of the values of the other type. 8对于具有相同签名和不同整数转换等级的任何两个整数类型(参见6.3.1.1),具有较小整数转换等级的类型的值范围是另一种类型的值的子范围。

    Since the integer conversion rank of signed long int is the same that unsigned long int , this implies that the range of values of size_t is contained in the range of values of unsigned long int . 由于signed long int整数转换等级unsigned long int相同,这意味着size_t的值范围包含在unsigned long int的值范围内。 But the item 3 in the list above left the door open to exceptions to this rule. 但是上面列表中的第3项为此规则的例外打开了大门。

So, we can only say that is highly intended that an implementation makes the values of size_t hold in the range of the unsigned long int . 因此,我们只能说实现高度意图使size_t的值保持在unsigned long int的范围内。 But we cannot be completely sure . 但我们不能完全确定

If you want to be sure, you can do the following procedure to check your system: 如果您想确定,可以执行以下步骤来检查系统:

  1. Include the files <limits.h> and <stdint.h> in order to access the information about integer types for your implementation. 包括文件<limits.h><stdint.h> ,以便访问有关实现的整数类型的信息。
  2. Compare the constants ULONG_MAX (from <limits.h> ) and SIZE_MAX (from <stdint.h> ). 比较常量ULONG_MAX (来自<limits.h> )和SIZE_MAX (来自<stdint.h> )。

A short program would be this: 一个简短的计划是这样的:

 #include <stdio.h>
 #include <limits.h>
 #include <stdint.h>

 int main(void) {
      printf("Is the range of size_t containd in that of unsigned long?\n\n");
      if (SIZE_MAX <= ULONG_MAX)
           printf("Yes");
      else 
           printf("No");
      return 0;
 }

According to the 1999 ISO C standard (C99), size_t is an unsigned integer type of at least 16 bit (see sections 7.17 and 7.18.3).

So sizeof(size_t) <= sizeof(unsigned long int) is true, but sizeof(size_t) > sizeof(unsigned long int) is not true and can lead to data loss. 因此sizeof(size_t) <= sizeof(unsigned long int)为true,但sizeof(size_t) > sizeof(unsigned long int)不为true,可能导致数据丢失。 For instance: 例如:

size_t a = b;

may cause data loss if b is an unsigned long int since its value can be grater than an size_t can hold. 如果bunsigned long int则可能导致数据丢失,因为它的值可能大于size_t可以容纳的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM