C++ 一元等于(一元运算符=)

逆向工程 二元分析 C++ qt
2021-06-15 07:14:07

在 C++ 二进制文件中,我发现 Qt 方法像??4QString@@QEAAAEAV0@AEBV0@@Zwhich demangle to

public: class QString & __ptr64 __cdecl QString::operator=(class QString const & __ptr64) __ptr64

或更短的形式,QString& QString::operator=(QString const&). 返回值似乎没有被使用。鉴于它似乎不是人们在原始代码中编写的构造,这个“一元等于”的目的是什么?

编辑

我找到了我困惑的根源。我完全接受了与 的调用约定this,以及operator=应该做什么。根据我的经验,人们this在逆向软件时将其表示为直接参数是很常见的例如,这就是 IDA 所做的。这也是我打算做的。所以,它被认为是一元的,因为我写的它只接受参数 ( this)。

事实证明,IDA 以某种方式错误地分配了类型,并给了它签名__int64 __fastcall QString__operator_(_QWORD)而不是QString* __fastcall QString__operator_(QString *, QString const *). 我不知道这是什么原因造成的。来自 [demangler.com] 的输出,我放在我帖子的前半部分,没有包含隐含的this,这与我的预期相反。

2个回答

这是相当有C++问题的,但尽管如此:

你看到的是类的赋值运算符QString它使您能够编写诸如a = b, where a, bareQString类型的内容。

它返回值的原因是使您能够编写:a = b = c而不是a = candb = c并且您可能会在其他运算符重载的情况下看到这种模式(例如参见问题)。

C++=如果不是由程序员编写,标准要求编译器生成运算符,因此即使不直接使用,您也可以期望它存在。

原语的默认赋值运算符返回一个值,运算符重载的标准约定是不偏离您正在重载的运算符的行为。这就是为什么继续从赋值重载运算符返回分配的引用是一种很好的做法。

由于这种行为,在 C(以及扩展到 C++)中有一个关于在赋值时检查函数的返回值的常用习惯用法。

例如,考虑对 realloc 的调用:

// int *ptr;
// size_t size;

size *= 2;
int *nptr = realloc(ptr, size);
if (nptr)
    ptr = nptr;
else
    return ERROR;

我们可以通过在 if 条件中移动赋值表达式来简化代码。在这里,我们利用了两个赋值表达式,size *= 2,它在加倍后返回变量的值,以及对 的赋值nptr,它在失败时NULL( 0)。

// int *ptr;
// size_t size;

int *nptr;
if (nptr = realloc(ptr, size *= 2))
    ptr = nptr;
else
    return ERROR;