数组索引和通常的算术转换

3
在C语言中,当我使用整数作为数组索引时,是否会触发常规算术转换规则将数组索引转换为某种整数类型?如果是,它会转换成哪种整数类型?
示例1:
int i = ...;
... a[i] ...

这个操作会触发整数转换或提升吗?如果是,i会被转换成什么类型? (unsigned int? size_t? 还是其他类型?)

例子2:

unsigned int j = ...;
... b[j] ...

这会触发整数转换或提升吗?如果是,i会转换成什么类型?
如果索引的类型不是int,那么它何时进行整数转换的规则是什么?是否应用了通常的算术转换规则,还是其他规则?
我也对指针算术的同样问题感兴趣,例如表达式p+i,其中p是一个指针,i是某种整数类型。
我查看了关于理解整数转换的CERT Secure Coding指南OWASP整数溢出概述,但两者都没有描述这种情况。下面的StackOverflow问题也没有: 整数转换(缩小,扩大),未定义行为

@JonathanLeffler,是的,我熟悉通常的转换。我的问题是:它们是否适用于此处,以及如何应用?通常的转换是应用于将数组索引转换为int还是其他类型 - 如果是其他类型,那么是哪种类型?管理此情况的规则是什么?我可以找到通常算术转换的文档,但它们似乎假定我已经知道目标类型应该是什么,而我无法确定数组索引的目标类型应该是什么。 - D.W.
C99 §6.5.2.1并没有声明该类型为“int”,而只是一个整数类型。 “其中一个表达式应具有‘‘指向完整对象类型的指针’’的类型,另一个表达式应具有整数类型,结果的类型为“type”。 - WhozCraig
非常酷,非常感谢@WhozCraig!那么这怎么应用在这里呢?对于我在问题正文中提出的问题有什么影响?如果索引已经是整数类型,那么是否不会应用任何提升或转换?再次感谢! - D.W.
@JonathanLeffler,太棒了,谢谢。您是否想将其转换为答案,以便我可以点赞/接受它?(还有一种情况:如果i的类型比int更大,则如何处理:longsize_tunsigned long等。但这对我来说不是很重要。) - D.W.
Jonathan很好地总结了这一点。如果有任何促销活动,都会在表达式本身中使用,但无论如何,在完成时必须是整数类型。也就是说,您不能使用ar [1.01]并期望从doubleint的晋升发生,因为它用作下标索引; 它不会。但是,只要x + y * z在完成其“我需要转换以满足此表达式”的操作后得出整数类型,您就可以执行ar [x + y * z]。我无法比这更好地描述它(至少在我阅读它时)。 - WhozCraig
显示剩余2条评论
1个回答

3
C99的第6.5.2.1节第2段规定如下:

......下标运算符[]的定义是E1[E2]等同于(*((E1)+(E2)))...

这意味着+运算符有以下规则:

对于加法,要么两个操作数都必须具有算术类型,要么一个操作数必须是对象类型的指针,另一个操作数必须具有整数类型。(递增相当于加1。)

因此,当+的第一个参数为指针时,第二个参数必须具有整数类型,且不进行转换。

注:

第一条引用中的E2是表达式,因此可以包含许多类型转换,因为它是计算出来的。重要的是,结果类型必须是整数类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接