2016-12-13 3 views
0

私は多様な関数と引数についていくつかの研究をしています。va_argでの鋳造方法

私は、va_argがオブジェクトを他のオブジェクトにキャストできることに気付きました。

ファンクションコール:

AddNumbers(3, 5, 'a', 20); 

関数宣言:

次の引数が charですが、それは intする必要がありますようにあなたが va_argを使用している場合例えば、それは char intへのキャスト
int AddNumbers(int count, ...) { 
    int result; 

    va_list va; 
    va_start(va, count); 
    for(int i = 0; i < count; ++i) { 
     result += va_arg(va, int); 
    } 
    return result; 
} 

私の質問は:どのような種類のキャスト(Cスタイル、ダイナミックキャストなど)ですか?

答えて

1

va_argはマクロであり、関数ではないので、正確にはキャスティングではありません。したがって、タイプva_arg(va, int)は、intによってです。

しかしプロモーションは可変引数関数を呼び出すときに省略記号の前の引数を除いて(発生。

をそうAddNumbers(3, 5, 'a', 20);で行う、文字'aは「int型に昇格されます。あなたは、あなたのコードと同じようにintとして使用するか、int型の値がchar型で表すことができるために定義されたchar(変換ではないキャスト)に戻します。

+0

可変引数をintに昇格する必要があることをどのように知っていますか? –

+1

@MZeinstra - コンパイラにはルールが組み込まれています。可変長関数に渡されると 'char'式が' int'に昇格します – StoryTeller

+0

@StoryTellerクラスについてはどうですか?それらはコンパイラに焼き付けることはできません。 –

1

私が正しくあなたの質問を理解していれば:可変引数関数を呼び出すときに

Cは、デフォルトでは、特定の「キャスト」を行います。 GCCはこれらをdefault argument promotionsと呼びます。彼らは以下のとおりです。

  • 符号付きまたは符号なしcharshort int符号付きまたは符号なしintなります。
  • floatは、doubleとなる。

これは本当にAddNumbers内のキャストをやっva_argの問題ではありません。その代わりにを呼び出すときには、AddNumbersをスタックにプッシュする際に、呼び出し側が引数をAddNumbersに昇格させるようにします。

3

キャスティングとは関係ありません。この場合、引数プロモーションのために動作します。

varargs関数を使用する場合、integer types smaller than int (like e.g. char) are promoted to int

これは、文字リテラルを関数に渡すときに機能する理由です。たとえば、次のような他のタイプを試してみてください。浮動小数点値なら、それはもはや機能しません。

va_argマクロ(ほとんどの場合、マクロとして実装されています)は、完全に実装に依存します。キャストはまったく行われないかもしれませんが、他の形式のtype punningを代わりに使用してください。

+0

基本的に正しい型であると仮定します。そうでなければ、ランタイムエラーが発生しますか? –

+2

@MZeinstra - エラーを引き起こす義務はありません。標準では未定義の動作です。 – StoryTeller

+1

C標準(これはC++からアクセス可能なC標準ライブラリの一部であるため関連しています)では、va_argはマクロとして実装され、 'va_arg(ap、type)' **の型は**型です。 –