- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
第 6.5.3.2 节“地址和间接运算符”¶3 说(仅相关部分):
The unary & operator returns the address of its operand. ... If the operand is the result of a unary
*
operator, neither that operator nor the&
operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue. Similarly, if the operand is the result of a[]
operator, neither the&
operator nor the unary*
that is implied by the[]
is evaluated and the result is as if the&
operator were removed and the[]
operator were changed to a+
operator. ...
这意味着:
#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)。
简化 &->
表达式在概念上(恕我直言)与 &[]
相同,一个简单的地址加偏移量。它甚至是一个可以在编译时确定的偏移量,而不是可能在运行时使用 []
运算符确定。
为什么这看起来如此不一致,有什么理由吗?
最佳答案
在您的示例中,&i[10]
实际上是不合法的:它变为 i + 10
,变为 NULL + 10
,并且您不能对空指针执行算术运算。 (6.5.6/8列出了可以进行指针运算的条件)
反正这个规则是C99加的;它不存在于 C89 中。我的理解是,添加它在很大程度上是为了使如下代码定义明确:
int* begin, * end;
int v[10];
begin = &v[0];
end = &v[10];
最后一行在 C89(和 C++)中在技术上是无效的,但由于这条规则在 C99 中是允许的。这是一个相对较小的变化,使常用的结构定义明确。
因为您不能对空指针执行算术运算,所以您的示例 (&s->b
) 无论如何都是无效的。
至于为什么会出现这种“不一致”,我只能猜测。很可能没有人想过让它保持一致,或者没有人看到一个令人信服的用例。这可能会被考虑并最终被拒绝。 the Rationale 中没有关于 &*
减少的评论.您或许可以在 the WG14 papers 中找到一些权威信息。 , 但不幸的是,它们的组织似乎很差,因此拖网搜索它们可能很乏味。
关于C 标准寻址简化不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4905512/
我正在尝试提供即时转码的视频。不幸的是,这意味着寻求不起作用。我假设这是因为浏览器不知道视频有多长,因此无法正确显示搜索栏。 有谁知道是否可以对视频的时长进行硬编码? 我想到的另一个选择可能是创建我自
我是一名优秀的程序员,十分优秀!