strncmp的这种用法是否包含读取的界限?

Bri*_*ian 13 c strncmp fortify

Fortify表示这是一个超出范围的读取:

if (strncmp("test string", "less than 32 char", 32) == 0)
{
...
}
Run Code Online (Sandbox Code Playgroud)

它说该函数从边界外读取数据less than 32 char.

如果strncmp超过32个字符并且第二个字符串少于32个字符,真的有一个发现吗?

nju*_*ffa 12

出于性能原因,标准字符串函数的实现通常将处理自然对齐的寄存器宽度块中的数据.这可能导致读取访问超过源数据对象的末尾,但是对齐保证代码的行为与内存异常的简单实现完全相同.每个宽访问都包含在单个页面中,并且没有触摸的页面也不会被逐字节实现所触及.

我会声称C的as-if规则涵盖了这样的实现,也就是说,它们的行为与它们遵循抽象功能规范的行为相同.

这种优化实现的一个例子是OpenSolaris strcmp()用于SPARC v8.这是我十五年前写的代码,以及其他性能优化的字符串函数.

然而,各种内存检查器工具会抱怨这样的代码,因为它的使用会导致访问超出分配的数据对象的限制,即使越界读取访问在设计上是无害的.


Sou*_*osh 10

TL; DR - strncmp()将继续比较字符串元素,直到任一字符串的结尾或32个元素(字符),以较少者为准.

(ny)字符串始终以空值终止,并且在遇到空终止符时,不执行进一步的比较.你的代码是安全的.

引用C11,章节§7.24.4.4(强调我的)

int strncmp(const char *s1, const char *s2, size_t n);
Run Code Online (Sandbox Code Playgroud)

strncmp函数比较不大于n字符(即跟随一个空字符的字符不进行比较)从阵列指向s1到阵列指向s2.


R S*_*ahu 6

你有完全有效的代码.

您的编译器生成错误的对象代码或强制报告误报.

我怀疑是编译器生成错误的代码.这将产生太多问题,并将立即被检测和修复.

fortify最有可能报告误报.