Gcc 使用 memcpy 作为隐式复制赋值运算符,而不是成员复制
Gcc uses memcpy for implicit copy-assignment operator instead of member-wise copy
遵循 C++ 11 标准,我认为每当完成两个对象之间的赋值时,G++ 都会隐式使用成员级副本。令人惊讶的是,我注意到与标准相反,g++ 似乎调用了一个大小为对象实际大小的 memcpy。下面是我的意思的片段。
#include <stdio.h>
class Classe {
public:
Classe(char m1 = 0, int m2 = 0) : membro1(m1), membro2(m2) {};
void setMembro1(char m1) {membro1 = m1;}
void setMembro2(int m2) {membro2 = m2;}
char getMembro1() const {return membro1;}
int getMembro2() const {return membro2;}
private:
char membro1;
int membro2;
};
Classe c;
void function() {
c = Classe('a', 1);
}
int main() {
char ciao[] = "HELLO!";
printf("Ciaon");
function();
printf("%dn", sizeof(Classe));
}
在执行结束时,我希望"c"对象所在的内存是{0x61,0x00,0x00,0x00,0x01,0x00,0x00,0x00},但显然,在第一个位置(包含0x61(旁边,"函数"函数数据的一些堆栈实际上被复制了,这是不正确的,恕我直言。
你知道发生了什么吗?非常感谢您的努力。
C++编译器
可以以它想要的任何方式实现成员的复制,只要结果符合C++规范。
在这种情况下,成员只是基本类型,并且底层架构不会妨碍,您的C++编译器可以很好地使用 memcpy(( 来执行复制。
在许多实现中,内存布局中char membro1
和对象中的char membro2
成员之间会有填充。
您在特定实现上看到的内存布局将意味着如下所示:
{0x61, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}
| | | | |__________________|
| padding| | |
| padding| membro2
membro1 padding
这 3 个填充字节中的内存内容没有指定,因此就C++而言,您以某种方式观察到的任何值都无关紧要 - 即使特定实现碰巧从堆栈中复制了该填充区域中的某些值。
相关文章:
- CRTP 中的复制赋值运算符 - gcc vs clang 和 msvc
- 为什么基类中的复制和交换会导致派生类中的复制赋值运算符被隐式删除?
- 在c++中重载复制赋值运算符
- 复制构造函数和复制赋值运算符是否应具有相同的语句?
- 移动赋值运算符与复制赋值运算符
- Gcc 使用 memcpy 作为隐式复制赋值运算符,而不是成员复制
- 如何在没有复制赋值运算符的情况下交换两个对象
- 模拟 C++ 中 lambda 的复制赋值运算符
- 重载复制赋值运算符
- 为什么C++编译器会创建复制构造函数和复制赋值运算符
- 默认的复制构造函数和复制赋值运算符给出奇怪的错误
- 重载运算符 = 返回 void 是否不可能成为复制赋值运算符
- 了解复制构造函数和复制赋值运算符
- 重载全常量类型的复制赋值运算符的正确方法是什么?
- 是具有复制和交换习惯用法的复制赋值运算符,建议进行自赋值检查
- 删除复制构造函数或复制赋值运算符算"user declared"吗?
- 为什么我们需要删除复制赋值运算符中的指针
- 重载非类型模板结构的成员结构的复制赋值运算符
- clang-libc++错误:重载解析选择了隐式删除的复制赋值运算符
- C++移动语义:为什么调用复制赋值运算符=(&)而不是移动赋值运算符=(&&)?