对于标量值,赋值运算符似乎将右侧值复制到左侧。这对复合数据类型如何起作用?例如,如果我有嵌套的结构
struct inner {
int b;
};
struct outer {
struct inner a;
};
int main() {
struct outer s1 = { .a = {.b=1}};
struct outer s2 = s1;
}
通过尝试似乎可以做到,但是任何人都可以指出行为规范吗?
答案 0 :(得分:4)
没有“递归”;它复制值的所有(值)位。当然,并不是神奇地遵循指针,赋值运算符不会知道如何复制指向的数据。
你会想到的
a = b;
简写
memcpy(&a, &b, sizeof a);
sizeof
当然是令人误解的,因为我们知道双方的类型都是相同的,但我认为__typeof__
并没有帮助。
C11规范草案说(在6.5.16.1简单分配中,第2段):
在简单赋值(
=
)中,右操作数的值将转换为 赋值表达式的类型,并替换存储在对象中的值 由左操作数指定。
答案 1 :(得分:2)
该分配是否递归地深度复制值?
是的,就像您将使用memcpy
一样。指针被复制,但不指向它们。 “深度复制”一词通常意味着:还复制指针指向的内容(例如在C ++复制构造函数中)。
除任何填充字节的值外,其他值可能都不确定。 (这意味着结构上的memcmp
可能是不安全的。)
将结构传递给函数时会发生同样的事情吗?
是的。请参阅下面对6.5.2.2的引用。
通过尝试似乎可以做到,但是任何人都可以指出行为规范吗?
C17 6.5.16:
赋值运算符将一个值存储在由左操作数指定的对象中。一个 赋值表达式具有赋值后的左操作数的值,但不具有 一个左值。赋值表达式的类型是左操作数应具有的类型 左值转换后。
(在这种情况下,左值转换无关紧要,因为两个结构必须都是100%相同且兼容的类型。简而言之:如果两个结构具有完全相同的成员,则它们是兼容的。)
C17 6.5.16.1简单分配:
- 左操作数具有结构或联合的原子,合格或不合格版本 类型与权利的类型兼容;
C17 6.5.2.2函数调用,第7节:
如果表示被调用函数的表达式的类型确实包含原型, 参数被隐式转换,就像通过赋值一样,...