在 public 函数中检查地址参数是否为 NULL

Check address parameters is NULL or not in public functions

我正在创建我的 onw strlen 函数,它将成为一个 public 函数,它适用于 x64 ...

现在我有一个关于将字符串地址传递给此函数的问题...此函数使用 RAX 寄存器获取字符串地址...现在我想知道是否真的有必要检查提供的地址是否等于是否为 NULL (0)?因为字符串地址可以是任何东西,即使提供的地址无效,也会发生崩溃!并没有必要在函数顶部执行此操作:

test rax, rax        ; string-address == 0 (NULL) ?
jz   .ret0

所以在public函数中,真的有必要检查提供的地址是否等于0吗?因为我认为这是一个额外的动作!!!! (即使是 public 函数)

这取决于您的函数做什么:

在很多API中传递一个NULL指针应该有一定的效果。例如,如果传递了 NULL 指针,您希望函数 returns -1

在这种情况下,您必须添加该检查。

也许您 运行 您的程序在地址 0 是有效地址的操作系统上。 (使用现代操作系统时情况并非如此,但在旧 (1996) Linux 版本下可能是这种情况)。

在这种情况下,如果字符串的第一个字符存储在地址 0

,您的 strlen() 实现也应该有效

这意味着您必须在这种情况下添加该检查。

In ISO C,使用 NULL 指针调用标准函数 strlen 是未定义行为。这并不要求/保证崩溃,它只是意味着有可能发生。 (恶魔也是从你的鼻子里飞出来的)。 UB 意味着任何事情都可能发生(不违反标准)。

显然在实践中,实际上 可能发生的事情通常不会那么多,当然大多数操作系统甚至根本不允许您映射零页。 (而且大多数 C/C++ 实现使用位模式 0 作为 nullptr / NULL 的对象表示,与 C/C++ 源级 0,尽管有趣的事实是 不需要 。)

所以大多数 strlen 实现只是从加载第一个字节开始。 (或者,如果它不会跨页,则加载前 16 个字节以使用 SSE2 无分支地检查零。 对 glibc 的 x86-64 asm strlen 实现进行了一些讨论。)

如果调用者想避免在 NULL 指针上崩溃,请在调用前进行检查。

写函数没有一个nullptr检查是完全有效的,只要合同的那部分被制定对于编写调用它的代码的人来说很清楚。

如果您在 asm 中手工编写(可能是出于性能原因),是的,您应该避免编写不需要的额外健全性检查,除非有一些有用的行为您实际上可以从多个调用者中排除, 到 strlen 的包装器中。 (例如,对于非 NULL,这属于正常的未经检查的 strlen,因此它只是在正常的 strlen 标签之前的额外几条指令。)

此外,您 return 对您的调用者输入 NULL 有什么用处? 0 意味着读取 ptr[0] 并找到 '[=17=]' 是安全的。也许这对某些来电者来说没问题。 size_t 是一个无符号类型,因此所有其他可能的值都是正数,也是一个有效的大小。