C 中数组索引的正确类型是什么? [英] What is the correct type for array indexes in C?

查看:25
本文介绍了C 中数组索引的正确类型是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C99 中的数组索引应该使用什么类型?它必须适用于 LP32、ILP32、ILP64、LP64、LLP64 等.它不必是 C89 类型.

What type for array index in C99 should be used? It have to work on LP32, ILP32, ILP64, LP64, LLP64 and more. It doesn't have to be a C89 type.

我找到了 5 个候选人:

I have found 5 candidates:

  • size_t
  • ptrdiff_t
  • intptr_t/uintptr_t
  • int_fast*_t/uint_fast*_t
  • int_least*_t/uint_least*_t

有简单的代码可以更好地说明问题.在这两个特定循环中 ij 的最佳类型是什么?如果有充分的理由,两种不同的类型也可以.

There is simple code to better illustrate problem. What is the best type for i and j in these two particular loops. If there is a good reason, two different types are fine too.

for (i=0; i<imax; i++) {
        do_something(a[i]);
}
/* jmin can be less than 0 */
for (j=jmin; j<jmax; j++) {
        do_something(a[j]);
}

附言在问题的第一个版本中,我忘记了负索引.

P.S. In the first version of question I had forgotten about negative indexes.

P.P.S.我不会编写 C99 编译器.然而,编译器程序员的任何回答对我来说都非常有价值.

P.P.S. I am not going to write a C99 compiler. However any answer from a compiler programmer would be very valuable for me.

类似问题:

推荐答案

我几乎总是将 size_t 用于数组索引/循环计数器.当然,在某些特殊情况下,您可能需要有符号的偏移量,但通常使用有符号类型有很多问题:

I almost always use size_t for array indices/loop counters. Sure there are some special instances where you may want signed offsets, but in general using a signed type has a lot of problems:

最大的风险是,如果调用者将事物视为未签名(或者如果您从错误信任的文件中读取它)传递了一个巨大的大小/偏移量,您可能会将其解释为负数并且无法发现它越界了.例如 if (offset 会写到不该写的地方.

The biggest risk is that if you're passed a huge size/offset by a caller treating things as unsigned (or if you read it from a wrongly-trusted file), you may interpret it as a negative number and fail to catch that it's out of bounds. For instance if (offset<size) array[offset]=foo; else error(); will write somewhere it shouldn't.

另一个问题是有符号整数溢出的未定义行为的可能性.无论您使用无符号还是有符号算术,都需要注意和检查溢出问题,但我个人发现无符号行为更容易处理.

Another problem is the possibility of undefined behavior with signed integer overflow. Whether you use unsigned or signed arithmetic, there are overflow issues to be aware of and check for, but personally I find the unsigned behavior a lot easier to deal with.

使用无符号算术的另一个原因(通常) - 有时我使用索引作为位数组的偏移量,我想使用 %8 和/8 或 %32 和/32.对于有符号类型,这些将是实际的除法运算.使用无符号,可以生成预期的按位和/位移操作.

Yet another reason to use unsigned arithmetic (in general) - sometimes I'm using indices as offsets into a bit array and I want to use %8 and /8 or %32 and /32. With signed types, these will be actual division operations. With unsigned, the expected bitwise-and/bitshift operations can be generated.

这篇关于C 中数组索引的正确类型是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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