5

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++ = '\0';
    return orig;
}

しかし、ここで glibc の実装を見ていると、なぜ大きすぎて複雑なのか疑問に思います。

「 time」コマンドを使用して実行時間をテストしました。どちらの機能もほぼ同じように動作します。
誰かが glibc strncpy()と my_strncpy() に欠けているものに関する知識を共有できますか?

4

1 に答える 1

1

現代の C プログラミングの観点から見ると、その「Glibc」コードは非常によく書かれていません。これは、32 ビット アライメントを使用する特定のプラットフォーム向けの時期尚早な最適化のコレクションのように見えます。コンパイラがくだらない場合は、バイトを優先アラインメントの単位でグループ化し、一度にそのような単位を 1 つずつコピーする必要があります。これが、コードが奇妙に見える主な理由です。

このコードは、コンパイラがコードを最適化するのがはるかに下手で、CPU がこれらのようなことをハードウェアでサポートしていなかったずっと前に書かれた可能性が高いと思います。前置と後置のインクリメントを行ったり来たりする一貫性のない一見ランダムな方法も、コードが貧弱なコンパイラ用に書かれていることを示唆しています。

時期尚早の最適化は別として、コードは完全なスパゲッティであり、賢明な説明はありません。コメントがまったくないことは、コードが悪いプログラマーによって書かれたことも示唆しています。

要約すると、彼らがこのようにコードを書いたのにはさまざまな歴史的理由があるかもしれませんし、ないかもしれません。

そのコードをゴミとして却下してください。


strncpyまた、この関数は主に廃止されているため、使用を避ける必要があることに注意してください。strncpyUnix の古代の文字列形式にのみ使用されることを意図していました。の安全なバージョンを意図したものではありませんでしたstrcpy。それどころか、この関数は危険であり、null 終端が誤って欠落しているため、多くのバグを引き起こすことが知られています。

の標準仕様ではstrncpy、事前に長さがわかっている場合に null 終端をチェックするなど、多くの無意味なことを行うことも強制されます。また、最初の文字の後に残りの文字を\0さらに\0. これらの無意味な要件はすべて、関数を不必要に遅くします。

strncpyしたがって、最新の C コードのどこでも使用する理由はありません。既知の長さの文字列をコピーする適切な方法は次のとおりです。

memcpy(str1, str2, str2len + 1);
于 2014-06-18T07:34:57.563 に答える