C標準ライブラリが提供する strncpy 関数の仕様について。


#define BUFSIZE 128
char dest[BUFSIZE];

void safe_store(const char* src)
  strncpy(dest, src, BUFSIZE);
  dest[BUFSIZE - 1] = '\0';  // ★



  • FreeBSD由来*2で非標準の strlcpy関数。ただし、GNU Cライブラリ(glibc)では意図的*3にstrlcpy関数を提供しない。
  • C11標準ライブラリ Annex.K Bounds-checking interfaces拡張((標準ヘッダstring.hのinclude前にマクロ__STDC_WANT_LIB_EXT1__を1で定義すると、strncpy_s関数が利用可能となる。))で定義される strncpy_s関数。ただし、全てのC11処理系で提供されるとは限らない。

C89(ANSI C)策定時の論理的根拠を説明する"Rationale for American National Standard for Information Systems - Programming Language - C"より引用。この説明文は(PDF)C99 Rationaleの7.21.2.4にもそのまま引き継がれている。 The strncpy function
strncpy was initially introduced into the C library to deal with fixed-length name fields in structures such as directory entries. Such fields are not used in the same way as strings: the trailing null is unnecessary for a maximum-length field, and setting trailing bytes for shorter names to null assures efficient field-wise comparisons. strncpy is not by origin a "bounded strcpy," and the Committee has preferred to recognize existing practice rather than alter the function to better suit it to such use.


2 The strncpy function copies not more than n characters (characters that follow a null character are not copied) from the array pointed to by s2 to the array pointed to by s1.269) If copying takes place between objects that overlap, the behavior is undefined.
3 If the array pointed to by s2 is a string that is shorter than n characters, null characters are appended to the copy in the array pointed to by s1, until n characters in all have been written.

脚注269) Thus, if there is no null character in the first n characters of the array pointed to by s2, the result will not be null-terminated.




*3:strlcpy関数によりバッファオーバーラン脆弱性は防げるが、文字列切り詰めによる意図しないデータ欠落もまたセキュリティ上の懸念となるという理由。詳細はThe ups and downs of strlcpy()参照。