nullsub_
的函数,根据IDA,这些函数不返回null
(只是ret
指令)。 那么,这些是什么,为什么它们在数据库中?
#1 楼
我从C ++的角度回答,其他语言也有不同的原因。这些函数有合法用途,即使它们仅不过是
void func(/* any args */) {}
我想到的一个例子是虚函数,该虚函数在基类中不执行任何操作,但在派生类中被覆盖。一个类似的示例是一个模板函数,其一般情况为空,而专门化条件为空。
另一种情况是静态变量。必须在程序结尾处调用静态变量析构函数,该函数通常在首次访问变量时使用
atexit
来注册析构函数回调。我记得,C ++标准说不会调用没有可观察行为的析构函数,但是我仍然看到MSVC 6.0将nullsub
s都注册为析构函数。全局变量遵循类似于静态变量的规则。
根据编译器的说法,另一种可能性是一个完全无效的函数。该函数必须存在,以防某些情况(例如,另一个不知道实现为空的编译单元)试图调用它,但其主体为空。
请记住,“根据编译器”并不总是等同于编码人员的理解。我本人曾经编写了一个清理函数,该函数做了很多工作,但是由于错误,它采用了值而不是引用的参数。编译器在没有任何警告的情况下将整个功能体优化为
{}
。糟糕。#2 楼
DCoders的回答很好,但是其他原因包括:在调试和发行版中,函数的主体#ifdef可能已被删除,但是保留函数调用以避免更改代码流。 br />
一个示例是调试打印功能
另一个原因是允许打补丁。这个很弱。
评论
因此,尽管优化标志处于打开状态,但编译器可能会故意将其保留?
– PhoeniX
13-10-10在6:58
并不是所有的优化都是平等的,也不是所有的编译器都是平等的。我想的示例来自非ARM / x86 CPU或80年代/ 90年代的代码。
– Simeon朝圣者
13年10月10日在22:23
评论
我认为您的意思是“根据IDA,它们什么也不会返回”(即一条简单的“ ret”指令)。这与null不同。例如,当过程是占位符时,就会发生这种情况。@peterferrie,你是对的。感谢您的纠正。