Renesas Synergy™

FAQ 105948 : プログラム例で、「aaa = (signed long)( BBB << CCC );」 式の右辺が 0x0000f000 になるのはなぜですか?VISUAL C++ では、0x0ffff000 になっています。

Q: 質問

プログラム例で、「aaa = (signed long)( BBB << CCC );」 式の右辺が 0x0000f000 になるのはなぜですか?VISUAL C++ では、0x0ffff000 になっています。

 

 

プログラム例 生成アセンブリコード

#define BBB (unsigned short)0xffff
#define CCC (unsigned char)12

signed long aaa;

test( void )
{
aaa = (signed long)( BBB << CCC );

}

_test:
    mov.w #0f000H,_aaa
    mov.w #00000H,_aaa+2  
    rts

 


A: 回答

コンパイラは、プログラム例の式を以下の順序で処理します。

  1. BBBをintに型変換
    (元がintで表現できる場合は、signed int)
    (元がintで表現できない場合は、unsigned int(以上))
  2. CCCでシフト
  3. signed longに型変換してaaaに格納

NC30 では、int型変数を16ビットで扱います。したがって、式 aaa = (signed long)( BBB << CCC ); を次のように処理します。

  1. 0xffff -> 0xffff (intで表現できないのでunsigned intへ型変換します)
  2. 0xffff<<12 -> 0xf000
  3. 0xf000は符号無しですから(signed long)にキャストしても 0x0000f000となります。 -> aaa

結果は、0x0000f000となります。

NC30 で式 aaa = (signed long)( BBB << CCC ); の結果を 0x0ffff000 にするには、シフトした結果を signed long にキャストするのでなく、変数 BBB をキャストするように記述してください。

#define BBB      (unsigned short)0xffff
#define CCC     (unsigned char)12

signed long aaa;

test( void )
{
          aaa = (signed long)BBB<<CCC;
}


上記プログラムをコンパイルした結果、次のアセンブリコードが生成されます。

;## # C_SRC :             aaa = (signed long)BBB << CCC;
          mov.w       #0f000H,_aaa
          mov.w       #00fffH,_aaa+2
(参考)
VISUAL C++ はint型を32ビットで扱います。
したがって、 VISUAL C++ では、式 aaa = (signed long)( BBB << CCC ); を次のように処理します。
  1. 0xffff -> 0x0000ffff
  2. 0x0000ffff <<12 -> 0x0ffff000
  3. 0x0ffff000 ->aaa
演算結果は、0x0ffff000 です。

適用製品

M16Cシリーズ,R8Cファミリ用C/C++コンパイラパッケージ [M3T-NC30WA]
他にご質問がございましたら、リクエストを送信してください