volatile int typecast return value. Could this make problem?

Hello experts, I'm a beginner of embedded system development.

I have question.about difference of two code.

at first, suppose there is function like

   int SomeFunction(void) {

      ......

       return (some integer);

}

And using this function return value like these

  • int retval;

       retval = SomeFunction();

       if (retval == {some Variable})  {

         . . .

       }

  • if ( {some Variable} == (volatile int) SomeFunction()) {

          ....

        }

    

former one doesn't make any problem, but when i used like latter one.. some times, retval is not correct and some strange value remains on r0 register...;

I don't know what is problem on latter one exactly...;

Could explain what is the problem of these?

Thank you very much for reading this..... though it is written by pool english...

Parents
  • Hello  levi,

    if the retval of the volatile function was incorrect, it would might be a bug of the compiler.
    The difference between
    retval = SomeFunction();
    and
    retval = (volatile int)SomeFunction();
    is whether the function must be executed for every call.
    In the case of several function calls of SomeFunction, if there would not be the volatile cast, the call might be executed once and the return value might be re-use for the other return values of the same functions.
    If there is the volatile cast, the function must be executed for every its function call.
    Therefore, if the return value is defined in one way according to the input arguments, the volatile cast has no means.
    The volatile cast would be used when the return value would vary at every call even if the input arguments are the same.

    For example, please refer to the following source code and assembled result.

    o Source Code

    int main()
    {
      int retval;
      retval = SomeFunction();
      if (retval == 0x11223344) {
        foo();
      }
      if (retval == 0x11223344) {
        bar();
      }
      if ( 0x11223344 == (volatile int) SomeFunction()) {
        foo();
      }
      if ( 0x11223344 == (volatile int) SomeFunction()) {
        bar();
      }
      return 0;
    }     
    
    

    o Assembled Result

    main:
            stmfd   sp!, {fp, lr}
            add     fp, sp, #4
            sub     sp, sp, #8
            bl      SomeFunction
            str     r0, [fp, #-8]
            ldr     r2, [fp, #-8]
            movw    r3, #13124
            movt    r3, 4386
            cmp     r2, r3
            bne     .L4
            bl      foo
    .L4:
            ldr     r2, [fp, #-8]  @ return value is re-used
            movw    r3, #13124
            movt    r3, 4386
            cmp     r2, r3
            bne     .L5
            bl      bar
    .L5:
            bl      SomeFunction
            mov     r2, r0
            movw    r3, #13124
            movt    r3, 4386
            cmp     r2, r3
            bne     .L6
            bl      foo
    .L6:
            bl      SomeFunction
            mov     r2, r0
            movw    r3, #13124
            movt    r3, 4386
            cmp     r2, r3
            bne     .L7
            bl      bar
    .L7:
            mov     r3, #0
            mov     r0, r3
            sub     sp, fp, #4
            ldmfd   sp!, {fp, pc}
     
    

    Best regards,
    Yasuhiko Koumoto.

Reply
  • Hello  levi,

    if the retval of the volatile function was incorrect, it would might be a bug of the compiler.
    The difference between
    retval = SomeFunction();
    and
    retval = (volatile int)SomeFunction();
    is whether the function must be executed for every call.
    In the case of several function calls of SomeFunction, if there would not be the volatile cast, the call might be executed once and the return value might be re-use for the other return values of the same functions.
    If there is the volatile cast, the function must be executed for every its function call.
    Therefore, if the return value is defined in one way according to the input arguments, the volatile cast has no means.
    The volatile cast would be used when the return value would vary at every call even if the input arguments are the same.

    For example, please refer to the following source code and assembled result.

    o Source Code

    int main()
    {
      int retval;
      retval = SomeFunction();
      if (retval == 0x11223344) {
        foo();
      }
      if (retval == 0x11223344) {
        bar();
      }
      if ( 0x11223344 == (volatile int) SomeFunction()) {
        foo();
      }
      if ( 0x11223344 == (volatile int) SomeFunction()) {
        bar();
      }
      return 0;
    }     
    
    

    o Assembled Result

    main:
            stmfd   sp!, {fp, lr}
            add     fp, sp, #4
            sub     sp, sp, #8
            bl      SomeFunction
            str     r0, [fp, #-8]
            ldr     r2, [fp, #-8]
            movw    r3, #13124
            movt    r3, 4386
            cmp     r2, r3
            bne     .L4
            bl      foo
    .L4:
            ldr     r2, [fp, #-8]  @ return value is re-used
            movw    r3, #13124
            movt    r3, 4386
            cmp     r2, r3
            bne     .L5
            bl      bar
    .L5:
            bl      SomeFunction
            mov     r2, r0
            movw    r3, #13124
            movt    r3, 4386
            cmp     r2, r3
            bne     .L6
            bl      foo
    .L6:
            bl      SomeFunction
            mov     r2, r0
            movw    r3, #13124
            movt    r3, 4386
            cmp     r2, r3
            bne     .L7
            bl      bar
    .L7:
            mov     r3, #0
            mov     r0, r3
            sub     sp, fp, #4
            ldmfd   sp!, {fp, pc}
     
    

    Best regards,
    Yasuhiko Koumoto.

Children