none
CT2Aマクロ RRS feed

  • 質問

  • 開発環境:
    Windows XP pro sp2
    Visual Studio 2005 VC

    CString FormatとCT2Aマクロに関する質問です。
    Unicodeビルドではなく、_MBCSでビルドしています。

     

    USES_CONVERSION;
    CString str = _T("ABCDEF");
    CStringA strA;
    strA.Format("%s %s", CT2A(str), "123");

     

    を実行すると、strA.Format()のところで異常終了してしまいます。
    ちなみに、
    CStringA strA;
    の宣言を
    CString strA;
    にしても異常終了してしまいます。
    CT2AマクロをやめてT2Aを使い
    strA.Format("%s %s", T2A((LPTSTR)(LPCTSTR)str), "123");
    とすると大丈夫です。
    CT2Aではなぜだめなのでしょうか?

    2007年9月5日 10:59

回答

  • 古い投稿へのレスで申し訳ありませんが
    C++の仕様上、一時変数は式が終了するまで破棄されませんので
    strA.Formatが呼び出された時点ではCT2Aのデストラクタは呼ばれません。

     

    検証するにはCT2Aのデストラクタにブレークポイントを仕掛け、
    以下のコードにステップインしてみるとよく分かるかと思います。

     

    strA.Format("%s %s", (LPCSTR)CT2A(str), "123");

     

    では何故例外が起きるのかというと、
    Formatメソッドは"%s"が指定されると引数の型のサイズがsizeof(int)と見なし
    sizeof(CT2A) != sizeof(int)であるので
    二つめ以降の引数を正常に取得できなくなるためです。

    • 回答の候補に設定 yayadon 2011年7月19日 14:46
    • 回答としてマーク 星 睦美 2015年12月1日 0:33
    2008年1月17日 6:51

すべての返信

  • CT2Aはマクロではなく、クラスです。
    ですので例のコードだと一時クラスとして使われてしまうため、strA.Formatが呼ばれた時点で
    すでに変換後の文字列領域がデストラクトされてしまいます。

    詳細はここですね。
    例のコードは「一時クラスのインスタンスに関する警告」のところで「不適切なコード例」として書かれています。
    http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/vclib/html/_atl_string_conversion_macros.asp
    2007年9月5日 11:09
  • ありがとうございます。

    CT2AはコンストTCHAR文字列をANSI文字列に変換するマクロだとばかり思っていました。

    T2CAとかあるので、CT2Aもマクロと決め付けていました。

    これでスッキリしました。

    ありがとうございました。

     

    • 回答としてマークされていない 星 睦美 2015年12月1日 0:33
    2007年9月5日 13:17
  • 古い投稿へのレスで申し訳ありませんが
    C++の仕様上、一時変数は式が終了するまで破棄されませんので
    strA.Formatが呼び出された時点ではCT2Aのデストラクタは呼ばれません。

     

    検証するにはCT2Aのデストラクタにブレークポイントを仕掛け、
    以下のコードにステップインしてみるとよく分かるかと思います。

     

    strA.Format("%s %s", (LPCSTR)CT2A(str), "123");

     

    では何故例外が起きるのかというと、
    Formatメソッドは"%s"が指定されると引数の型のサイズがsizeof(int)と見なし
    sizeof(CT2A) != sizeof(int)であるので
    二つめ以降の引数を正常に取得できなくなるためです。

    • 回答の候補に設定 yayadon 2011年7月19日 14:46
    • 回答としてマーク 星 睦美 2015年12月1日 0:33
    2008年1月17日 6:51
  • 一時変数の寿命による説明に納得がいかなかったのですが、正しい解説がなされていて助かりました。

    ちなみに64bit環境だと、%s書式が指定されたときに可変個引数リストから読み取る値のサイズはsizeof(__int64)となる、ということを補足させていただきます。

    2015年11月30日 15:32