FAQ 1011703 : 関数の戻り値に、意図した値が設定されません。

Q : 質問

関数の戻り値に、意図した値が設定されません。


A : 回答

関数のプロトタイプ宣言が記述されているかご確認ください。 記述されていない場合は、プロトタイプ宣言を追加してください。

関数の戻り値がunsigned char/unsigned short/ singned char / signed short型で、かつ、当該関数のプロトタイプ宣言を記述していない場合、戻り値はsigned int型として扱われます。

デ フォルトのオプション設定の場合、 呼び出し先の関数内で、返り値の符号/ゼロ拡張は行いません。 例えば、戻り値がunsigned char型の場合、呼び出し先では、 R0(4バイト)の上位3 バイトの内容は保証されませんので、 呼び出し元で返り値の符号/ゼロ拡張を行います。 呼び出し元での返り値の符号/ゼロ拡張は、プロトタイプ宣言に基づき実施されますが、 プロトタイプ宣言が記述されていない場合はsigned int型として扱われるため、 符号/ゼロ拡張が実施されません。
このため、R0(4バイト)の上位3 バイトに意図しない値が設定される可能性があります。

・Cソース例

test1.c
 extern unsigned char func(char,char);  //★
  void main(void)
 {
    volatile int ret;
    volatile char a,b;
    ret=func(a,b);
 }
 
test2.c
  unsigned char func(char x,char y){
    if(x>y){
       return x;
    }
  }

・アセンブリ例(test1.cに★プロトタイプ宣言が無い場合)

   _main:                 
            STS.L       PR,@-R15
            ADD         #-12,R15
            MOV.B       @R15,R4    ; a
            MOV.B       @(4,R15),R0; b
            MOV.L       L11+2,R2   ; _func
            JSR         @R2
            MOV         R0,R5
            MOV.L       R0,@(8,R15); ret  ;返り値をsigned int型として扱うため、ゼロ拡張されない
            ADD         #12,R15
            LDS.L       @R15+,PR
            RTS/N

・アセンブリ例(test1.cに★プロトタイプ宣言がある場合)

   _main:                    
           STS.L       PR,@-R15
           ADD         #-12,R15
           MOV.B       @R15,R5    ; b
           MOV.B       @(4,R15),R0; a
           MOV.L       L11,R1     ; _func
           JSR         @R1
           MOV         R0,R4
           EXTU.B      R0,R6       ;返り値がゼロ拡張される
           MOV.L       R6,@(8,R15); ret
           ADD         #12,R15
           LDS.L       @R15+,PR
           RTS/N

なお、-rtnextオプションを指定いただくと、 呼び出し先で 関数の返り値の符号/ゼロ拡張を行うことが可能です。

・アセンブリ例(-rtnextを指定した場合)

   _func:                                         
          EXTS.B      R4,R2
          EXTS.B      R5,R5
          CMP/GT      R5,R2
          BF          L11
     L11:
          RTS
          EXTU.B      R2,R0   ;返り値がゼロ拡張される

 

詳細はユーザーズマニュアルの以下をご参照ください。
・SHCコンパイラユーザーズマニュアル

  • 9.3.2 関数呼び出し規約
    表 9.7 リターン値の型と設定場所
  • 2. C/C++コンパイラ操作方法
    2.2.5 その他オプション
    RTnext

 

適用製品

SuperHファミリ用C/C++コンパイラパッケージ
他にご質問がございましたら、リクエストを送信してください