よろしくお願いします。
.NET2005 ユニコードライブラリで、TCHER型を使う場合、
TCHER tch[10];
_stprintf_s( tch1, 20, _T("値は%dです"), 20 );
というように、第2引数にバッファサイズを置かないといけないと思っていて、実際にビルドは通らなかった記憶があります。
ネット検索をしてみても、バッファサイズが必要だと書いてあります。
ところが、昨日、なにげに
_stprintf_s( tch1, _T("値は%dです"), 20 );
としたら、通ってしまいました。
ブレークポイントを置いて見ても、値は正しく代入されています。
どこかで私が初歩的な勘違いをしているのかもしれませんが、
なにかご存じの方がいらしたら、アドバイス頂けませんでしょうか。
_stprintf_sのリファレンスをご覧になりましたか?
C++言語であれば、第一引数がTCHAR型配列であれば
templateをつかう_stprintf_s関数が呼ばれます。
(そのなかでtemplateをつかわない_stprintf_s関数が呼ばれる)
Blueさん、ありがとうございます。
実は、初心者で、「_stprintf_sのリファレンス」の見方が分りません。
MSDNやネットでいろいろ検索してみましたが、見つけることができませんでした。
不思議なのは、以前使った時はバッファサイズが必要だったのに、今回はなくても通ってしまうことです。
.NET2005で、全く同じように作成したはずなのに、その違いが起きた原因が分かりません。
http://search.microsoft.com/results.aspx?setlang=ja-JP&mkt=ja-JP
で検索してください。
>不思議なのは、以前使った時はバッファサイズが必要だったのに、今回はなくても通ってしまうことです。
>.NET2005で、全く同じように作成したはずなのに、その違いが起きた原因が分かりません。
ですからtemplateのおかげです。
配列であれば要素数を取得することが出来るのです。
template <size_t size>
int sprintf_s(
char (&buffer)[size],
const char *format [,
argument] ...
); // C++ only
sizeに値が取れる。
Blueさん、ありがとうございます。
目的のページはヒットしました。
でも、「理解しました」には、ほど遠いと思います。
>不思議なのは、以前使った時はバッファサイズが必要だったのに、今回はなくても通ってしまうことです。
>.NET2005で、全く同じように作成したはずなのに、その違いが起きた原因が分かりません。
ですからtemplateのおかげです。
全く同じように開発環境でアプリケーションを新規作成して、自動的にテンプレート宣言が行われる場合と、そうでない場合があるのでしょうか。
初心者で、templateを意識したことはあまりなく、特別なコードの追加もしていません。
同じ_stprintf_sを使うにしても前述どおり引数の型に依存します。
たとえば、
TCHAR str[256];
である場合
_stprintf_s(str, _T("%d"), 10);
でも
_stprintf_s(str, sizeof(str) / sizeof(str[0]), _T("%d"), 10);
でもどちらでもOKですが、
TCHAR str[256];
TCHAR* p = str; // もしくは p = new TCHAR[256]; 等
である場合に第一引数にpを指定するとTCHAR配列型ではなくTCHARポインタ型であるため
_strprintf_s(p, 256, _T("%d"), 10);
のパターンの呼び出ししかできません。
(C言語のみの場合はtemplate自体がないのでサイズを指定するしかない)
おそらく、以前はサイズを指定しなければならなかったというのは、
第一引数にTCHAR配列型ではなく、TCHARポインタ型を指定していたのではないのでしょうか?
>自動的にテンプレート宣言が行われる場合と、そうでない場合があるのでしょうか
は、C++言語の場合同じ関数名でも引数の型や数が違えば違う関数として
解釈されるので、自動的に宣言が増えるとかそういうことはないと思われます。
(あるとすれば、C言語かC++言語かだけでしょう。)
一応、サンプル的なコード。
※VC6ではコンパイルできません。
// 引数としてint型で配列数が10の配列のポインタを指定する
void A(int (*n)[10]) {}
// 引数としてint型で配列数が10の配列の参照を指定する
void B(int (&n)[10]) {}
// 引数としてint型で配列数がsizeの配列の参照を指定する
template<size_t size>
void C(int (&n)[size]) {}
// 引数としてint型のポインタを指定する(配列型ではない)
void D(int* p) {}
int main()
{
int n1[10], n2[20];
A(&n1);
//A(&n2); // C2664(配列数が合わないため型が不一致)
B(n1);
//B(n2); // C2664(配列数が合わないため型が不一致)
C(n1);
C(n2);
D(n1);
D(n2);
return 0;
}
たいへんありがとうございました。
理解できたと思います。
ツイート | ![]() |