在glibc中,C -强实现过于复杂



我试图理解string.h函数。下面是我自己实现的strncpy()

char * my_strncpy(char *dst, const char* src, int n)
{
    char *orig = dst;
    const char *hold = src;
    int count = 0, remain = 0;
    while(*(hold++))
            count++;
    if ( n > count )
    {
            remain = n - count;
            n = count;
    }
    while(n--)
            *dst++ = *src++;
    while(remain--)
            *dst++ = '';
    return orig;
}

但是当看到这里的glibc实现时,我想知道为什么它太大太复杂。

我使用"time"命令测试执行时间。这两个函数的运行方式几乎相同。
是否有人可以分享关于glibc strncpy()的知识以及我在my_strncpy()中缺少的内容。

从现代C编程的角度来看,"Glibc"代码写得非常糟糕。它看起来像是针对一个具有32位对齐的特定平台的过早优化的集合。如果编译器是垃圾,那么您将不得不以首选对齐方式为单位对字节进行分组,并一次复制一个这样的单元。这就是为什么代码看起来如此奇怪的主要原因。

我猜这段代码可能是很久以前写的,当时编译器在优化代码方面差得多,cpu对这些东西的硬件支持也很少。它们在前缀和后缀增量之间来回切换的不一致、看似随机的方式也表明,这段代码是为一个糟糕的编译器编写的。

除了早熟的优化之外,代码完全是意大利面条,没有合理的解释。完全没有注释也表明代码是由一个糟糕的程序员编写的。

所以总结一下,他们以这种方式编写代码可能有也可能没有各种历史原因,但代码中有许多糟糕的编程实践,不能被视为过早的优化。

把这段代码当作垃圾扔掉。


还请注意,strncpy函数主要是过时的,应该避免使用。strncpy在Unix中只用于一种古老的字符串格式。它从未打算成为strcpy的安全版本。相反,该函数是危险的,并且由于意外丢失null终止而导致许多错误。

strncpy的标准规范还强制它做许多无意义的事情,比如在您已经提前知道长度的情况下检查null终止。此外,有人可能会想,用更多的填充第一个之后的剩余字符对任何人都有什么好处。所有这些毫无意义的要求都使函数变得不必要地慢。

所以没有理由在现代C代码中使用strncpy。复制已知长度字符串的正确方法是:

memcpy(str1, str2, str2len + 1);

相关内容

  • 没有找到相关文章

最新更新