2010-12-29 12 views
2

すべて、C++ va_argタイプキャストの問題

私は小さなC++アプリケーションを作成しており、この問題で困惑しています。要素の型が予期していない場合、va_argを使用してva_listマクロから要素にアクセスする際に、エラーを作成(および後でキャッチ)する方法はありますか?例えば: -

count=va_arg(argp,int); 
if (count <= 0 || count > 30) 
{ 
     reportParamError(); return; 
} 

私が代わりにint型のtypedefのを渡していた場合、私はMSのコンパイラにゴミ値を取得しますが、時間数の95%が(64ビットSLES10 sysの上)はgccに値0を取得します。いくつかの型チェックを強制する方法があるので、catchブロックで捕らえることができるエラーが出ますか?

これに関するアイデアは私にとって非常に役に立ちます。または、これを行うためのよりよい方法があります。関数のプロトタイプは次のとおりです。 -

void process(App_Context * pActx, ...) 

機能がpActxが第一パラメータとして渡されるので、として第一パラメータを数える渡すことはできませんことが不可欠である

process(pAtctx,3,type1,type2,type3); 

と呼ばれています。


更新-1

[OK]を、これは奇妙に聞こえるがNARGSは、SLES10のgccの上のva_listの一部にはいないようです。私はNARGSを以下のパラメータは、ゴミ値を得ることはありません、これを使用した後

#ifdef _WIN32 
tempCount=va_arg(argp,int) 
#endif 

に入れていました。しかし、これはコンパイラ/プラットフォームベースの#ifdefsを導入しています....ありがとうChrisとKristopher

+1

なぜカウントを2番目のパラメータにしないのですか? 'void process(App_Context * pActx、std :: size_t nargs、...); ' –

+0

@Chris、あなたの提案に感謝します。私はそのオプションを持っていましたが、gccでは、nargs後の1番目のパラメータ(type1)がガベージ値を取得しています。最後のパラメータもガベージ値を取得します。私は、nargsはva_list(argp、App_Context *)の後ろにva_list(argp、int)が続くva_listの一部であると仮定します。 – confused

答えて

2

いいえ、ありません。 varargsは、渡されたパラメータの型をチェックする方法を提供しません。型の情報を伝達する別の方法が必要であることを意味する正しい型だけを読み込む必要があります。

本当に必要な場合を除き、可変機能を避ける方がよいでしょう。 printfや友人のようなレガシー機能のためのC++機能だけです。

+0

迅速な対応をありがとう。 – confused

+0

+1ここでの根本的な問題は、 'main'が標準で定義されているように型が安全でないことです。 –

5

あなたはカウントは常に2番目の引数として渡されます知っているなら、あなたはいつもこれに署名を変更することができます:

void process(App_Context * pActx, int count, ...) 

それはオプションではありません場合は、それをキャッチする方法は本当にありません。これは、可変引数リストの仕組みがどのように機能するかです。呼び出し元が渡す情報以外に、呼び出し元がどの引数が渡されているかを知る方法はありません。

va_argマクロおよび関連するマクロがどのように実装されているかを調べると、スタック上のすべてのものを検査する方法を見つけ出すことができます。ただし、これは移植性がありません。また、デバッグの補助として以外は推奨されません。

関数のオーバーロード、テンプレート、またはvectorまたはlistの引数を渡すなど、可変引数の代替方法を調べることもできます。

+0

あなたの提案に感謝します。私があなたが言及したアプローチを試みました。私はこのアプローチの問題に直面した。 countの後の最初の引数は、64ビットのsles10システムで常にガベージ値を得ました。 va_listは.cファイルに由来します。いくつかの基本的なチェックの後、va_listは.cppファイルに渡されます。ごみの問題が現れる場所。 .c関数では、va_start(argp、App_Context *)を実行しました。 count = va_arg(argp、int)それからプロセス(pActx、count、argp)を呼び出します。その中にはva_arg(argp、type1)があります。 type1は常にガベージ値を持っているので、私はアプローチを変更しなければなりませんでした。 – confused