【问题标题】:C: cast int to size_tC:将 int 转换为 size_t
【发布时间】:2023-11-22 16:50:01
【问题描述】:

在 32 位和 64 位 Linux 平台上,在 C99 中将 int 转换/转换为 size_t 的正确方法是什么?

例子:

int hash(void * key) {
    //...
}

int main (int argc, char * argv[]) {
    size_t size = 10;
    void * items[size];
    //...
    void * key = ...;
    // Is this the right way to convert the returned int from the hash function
    // to a size_t?
    size_t key_index = (size_t)hash(key) % size;
    void * item = items[key_index];
}

【问题讨论】:

  • 我不明白为什么它不起作用。
  • 普通的普通演员(size_t)有什么问题?它在某种程度上不“正确”吗?
  • 是的,没错,虽然我认为它是隐式转换的,所以你并不真的需要(size_t)
  • 根本不投射有什么问题?

标签: c casting int c99 size-t


【解决方案1】:

所有算术类型都在 C 中隐式转换。很少需要强制转换 - 通常仅当您想要向下转换、减少模 1 加上较小类型的最大值时,或者当您需要强制算术为无符号时模式来使用无符号算术的属性。

就个人而言,我不喜欢看演员表,因为:

  1. 它们是丑陋的视觉混乱,而且
  2. 他们向我建议,编写代码的人收到有关类型的警告,并在不了解警告原因的情况下进行强制转换以关闭编译器。

当然,如果你启用了一些超挑剔的警告级别,你的隐式转换可能会导致很多警告,即使它们是正确的......

【讨论】:

    【解决方案2】:
    size_t key_index = (size_t)hash(key) % size;
    

    没问题。你实际上甚至不需要演员表:

    size_t key_index = hash(key) % size;
    

    做同样的事情。

    【讨论】:

      【解决方案3】:

      除了转换问题(如前所述,您不需要)之外,还有一些更复杂的事情可能会导致代码出错。

      如果hash() 应该返回一个数组的索引,它也应该返回一个size_t。因为它没有,所以当key_index 大于INT_MAX 时,您可能会得到奇怪的效果。

      我会说sizehash()key_index 应该都属于同一类型,可以肯定的是size_t,例如:

      size_t hash(void * key) {
          //...
      }
      
      int main (int argc, char * argv[]) {
          size_t size = 10;
          void * items[size];
          //...
          void * key = ...;
      
          size_t key_index = hash(key) % size;
          void * item = items[key_index];
      }
      

      【讨论】:

      • 我在 C99 标准中找不到任何将数组索引限制为小于 INT_MAX 的内容。如果你得到奇怪的效果,那就是编译器错误。显然在10 < INT_MAX 给出的示例中,因此任何一种方式都不应该有问题。