_tcscpy_s (strcpy_s, wcscpy_s) の引数

深いディレクトリの削除を再帰的に行う。(ReadOnlyの場合も対応) を使おうとして気づいた事.cstring の文字列処理関数を使おうとすると CRT のセキュリティ機能 関係の警告がよく出てきます.めんどくさいから警告を抑止しようかと思ったのですが,ふと strcpy_s の引数を見ると面白い事に気づきました.

template <size_t size>
errno_t strcpy_s(
   char (&strDestination)[size],
   const char *strSource 
); // C++ only

template <size_t size>
errno_t wcscpy_s(
   wchar_t (&strDestination)[size],
   const wchar_t *strSource 
); // C++ only

template <size_t size>
errno_t _mbscpy_s(
   unsigned char (&strDestination)[size],
   const unsigned char *strSource 
); // C++ only
strcpy_s、wcscpy_s、_mbscpy_s

C++ の場合の strcpy_s 系関数はテンプレートを使用しているものも用意しているようで,第1引数に配列を指定する限りは,ユーザ(呼び出し側)が引数で明示的に要素数を指定しなくても良いようになっているようです.なので,多くの場合は呼び出し側は引数を変更する必要はなく,関数名に _s を付けるだけで良いようになっている模様.

追記: _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES

闇の軍団的には_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES はどうなんだろう? RT @tt_clown: _tcscpy_s (strcpy_s, wcscpy_s) の引数 - http://t.co/BYzdZfng

http://twitter.com/#!/TKinugasa/status/121107078864584704

_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES なんてオプションがあったんですね.

テンプレート オーバーロードを使用することもできます。 _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES を 1 に定義すると、セキュリティが強化されたバリアントを自動的に呼び出す、標準 CRT 関数のテンプレート オーバーロードが有効になります。_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES が 1 の場合、コードを変更する必要はありません。 内部では、strcpy の呼び出しが strcpy_s の呼び出しに変換され、サイズ引数が自動的に指定されます。

#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1

...

char szBuf[10];

strcpy(szBuf, "test"); // ==> strcpy_s(szBuf, 10, "test")

_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES は、strncpy などのカウントを取る関数には影響しません。 カウント関数に対するテンプレート オーバーロードを有効にするには、_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT を 1 に定義します。 ただし、定義する前に、コードがバッファー サイズではなく (よくある間違い)、文字数を渡しているかどうかを確認しておく必要があります。 また、セキュリティが強化されたバリアントを呼び出す場合、関数の呼び出し後、バッファーの最後に明示的に null 終端文字を書き込むコードが必要です。 切り捨て動作が必要な場合については、_TRUNCATE の説明を参照してください。

セキュリティ保護されたテンプレート オーバーロード

コンパイラとの互換性を考えると _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES を使うのが一番良いのかなと言う気はします.