【发布时间】:2015-01-21 01:59:15
【问题描述】:
我了解 C 标准禁止将数组用作(可修改的)左值,即在赋值的左侧:
int lhs[4], rhs[4] = {0, 1, 2, 3};
lhs = rhs; /* illegal! */
现在,我一直想知道为什么会这样。我可以看到上面的语句(以及写入数组的任何其他赋值)被定义为等同于
memcpy((void *) lhs, (void *) rhs, sizeof(lhs));
并施加确保rhs 对用户足够大的负担,但没有决定应该是这种情况。
然而,一个非常相似的例子确实工作得很好:
struct { int a[4]; } lhs, rhs = {{0, 1, 2, 3, 4}};
lhs = rhs;
只需将数组包装在一个结构中,我们就可以准确地得到上述行为,即赋值lhs = rhs等价于:
memcpy((void *) &lhs, (void *) &rhs, sizeof(lhs));
这种(我觉得)不一致的原因是什么?允许将数组赋值解释为memcpys 有什么问题吗?
【问题讨论】:
-
这里回答:stackoverflow.com/a/17691191/14955(向下滚动到 Edit2:真正的原因)
-
一个数组名是一个左值。我认为您要问的是为什么数组不可分配。
-
@Thilo - “真正的原因”也不能很好地解释这一点。对于大多数处理器,访问数组不需要运行时指针。在编译时,数组的大小(对于 C 的早期版本)和相对(相对于目标文件)位置都是已知的,因此数组可以是可分配的。您可以使用数组定义一个结构作为它的唯一成员,并且该结构是可分配的。早于 C 的其他语言(例如 APL 或 Cobol)允许分配数组,所以我不清楚为什么选择它以 C/C++ 中的方式实现数组。
-
我觉得“真正的原因”并没有回答我的问题。当然,您不能“覆盖”内存 location(数组可以被解释为它;这似乎与 Ritchie 的直觉有些一致),但您可以写入它的 contents (就像结构一样)。除此之外,很明显,分配给指针 value 是没有意义的(不是双关语),但是 数组不是指针,它们的行为就像它们在某些上下文中一样.为什么你不能将赋值的左侧定义为 not 是这些上下文之一?