暗黙的な型変換の規則(アップキャスト)

CC-RLコンパイラでは暗黙的なアップキャストをどのように規定しているのでしょうか?

以下は問題が起きたコードです。
(★)部分:右辺を暗黙的にint32_tにアップキャストしてくれることを期待しましたが,実際にはint16_tで計算を進めて,桁落ちが発生しているようです。

------------------------------------------------------------
int32_t dy;
int16_t delta_1 = 10;
int16_t delta_2 = 20;

dy = (delta_2 - delta_1) * 10000; // (★)
------------------------------------------------------------

期待値 dy= 100,000
実 際 dy = -31,072(桁落ち)

案の定,明示的にアップキャストすれば解決しますが。。。

dy = (int32_t)(delta_2 - delta_1) * 10000;
もしくは
dy = (delta_2 - delta_1) * (int32_t)10000;


gccコンパイラではそもそも問題にならなかったりと,コンパイラ依存な感じがあります。
CC-RLコンパイラではどのように解釈・処理されるのでしょうか?

よろしくお願いします。

  • 整数リテラル10000がデフォルトで16ビットで扱われるので全て16bitとして扱って計算して最後の代入で32bitにしていると思います。なので掛け算した時にオーバーフローしますね。

    10000の代わりに10000Lとしてlong指定しておけば予期した通りビルドされると思います。

  • なお他の環境ではlongが32bitではなく64bitかもしれないのでキャストは明示的に書いた方がトラブルが少ないと思います。

  • わわいです

    勝手にアップキャストされるのは、intのサイズまでです。

    RL78のintのサイズは16ビットですんで、そのサイズまでしか拡張してくれません。

    #ってか、デフォルトではすべての整数計算はintのサイズで行われるってだけの話ですな

  • Yamamotoさん,わわいさん

    ありがとうございます。
    理解が深まりました。