第 §6.5.3.2 节“地址和间接运算符”¶3 说(仅相关部分):
一元 & 运算符返回其操作数的地址。...如果操作数是一元运算符的结果,则该运算
*
符和该&
运算符都不会被计算,并且结果就像两者都被省略了,除了对运算符的约束仍然适用并且结果不是左值。类似地,如果操作数是[]
运算符的结果,则不会计算&
运算符和*
隐含的一元,[]
结果就像&
删除了运算符并将[]
运算符更改为+
运算符一样。...
这意味着:
#define NUM 10
int tmp[NUM];
int *i = tmp;
printf("%ti\n", (ptrdiff_t) (&*i - i) );
printf("%ti\n", (ptrdiff_t) (&i[NUM] - i) );
应该是完全合法的,打印 0 和NUM
(10)。标准似乎很清楚,这两种情况都需要优化。
但是,它似乎不需要优化以下内容:
struct { int a; short b; } tmp, *s = tmp;
printf("%ti\n", (ptrdiff_t) (&s->b - s) );
这似乎非常不一致。我看不出上面的代码不应该打印sizeof(int)
加号(不太可能)填充(可能是 4)。
简化&->
表达式在概念上(恕我直言)与&[]
简单的地址加偏移量相同。它甚至是一个可以在编译时确定的偏移量,而不是潜在的[]
操作员运行时。
为什么这看起来如此不一致,有什么理由吗?