struct A { // some fileds... char buf[SIZE]; }; A a; a = a;
通过A的字段buf,看起来默认的赋值操作可能会调用类似memcpy的东西来将对象X分配给Y,那么如果将对象分配给自身并且没有定义明确的赋值操作,如a = a;以上.
memcpy手册页:
DESCRIPTION The memcpy() function copies n bytes from memory area src to memory area dest. The memory areas must not overlap. Use memmove(3) if the memory areas do overlap.
如果使用memcpy,可能会出现一些未定义的行为.
那么,C对象中的默认赋值操作行为是什么?
解决方法
The implicitly-defined copy/move assignment operator for a non-union
class X performs memberwise copy/move assignment of its subobjects.
The direct base classes of X are assigned first,in the order of their
declaration in the base-specifier-list,and then the immediate
non-static data members of X are assigned,in the order in which they
were declared in the class definition. Let x be either the parameter
of the function or,for the move operator,an xvalue referring to the
parameter. Each subobject is assigned in the manner appropriate to its
type:[…]
— if the subobject is an array,each element is assigned,in the
manner appropriate to the element type;[…]
如您所见,每个char元素都将单独分配.这总是安全的.
但是,在as-if规则下,编译器可以用memmove替换它,因为它对char数组具有相同的行为.它也可以用memcpy替换它,如果它可以保证memcpy会导致同样的行为,即使理论上这样的事情是未定义的.编译器可以依赖于理论上未定义的行为;存在未定义行为的原因之一是编译器可以将其定义为更适合其操作的任何内容.
实际上,在这种情况下,编译器可以进一步采用as-if规则,并且根本不对数组执行任何操作,因为这也会导致相同的行为.