This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

C51: 32 bits unsigned returned values treated as signed 16 bits

Hi!

In a full project a simple unsigned long ( u32 )returned value from a function lead to this (odd) assembler code.
It make us think that the u32 is considered as s16 ( signed short ).

If the sub-function th_microSecondsNow() returns the u32 0x0000FFCA the local_us returned will be 0xFFFFFFCA.
If the returned u32 is 0x00120233 the local_us returned will be 0x00000233.

For example the value is well settled in R4 = 00, R5 = 12, R6 = 02, R7 = 33 but at the end
R4 = 00, R5 = 00, R6 = 02, R7 = 33

We tried the same code in an empty project and in this case the function's behaviour is totally normal ( returned local_us values 0x0000FFCA or 0x00120233 ).

Any Ideas of what went wrong?

Many thanks in advance.

//please find below the assembler code abstract

   271: u32 microSecondsNow(void)
   272: {
   273:     u32 local_us;
   274:     local_us = th_microSecondsNow();
C:0x8DCB    1287A5   LCALL    th_microSecondsNow(C:87A5)
C:0x8DCE    EE       MOV      A,R6
C:0x8DCF    33       RLC      A
C:0x8DD0    95E0     SUBB     A,ACC(0xE0)
C:0x8DD2    FD       MOV      R5,A
C:0x8DD3    FC       MOV      R4,A
C:0x8DD4    900D1C   MOV      DPTR,#0x0D1C
C:0x8DD7    121DD0   LCALL    C?LSTXDATA(C:1DD0)
   275:     return local_us;

Parents
  • Another step towards understanding of the problem.

    The header file containing the function th_microSecondsNow() was missing.

    So the prototype ( u32 th_microSecondsNow(void); )was missing but the compiler did not complain unless with a warning

    warning C206: 'th_microSecondsNow': missing function-prototype
    

    Naturally during first steps of development the number of warning is huge and this one was completely lost among the others

    As I had tried to introduce a new function:

    void th_microSecondsNow_2(u32 * ptr);
    


    I obtained an error. Why a warning in one case and an error in the other case, while the 2 functions are written one just below the other ??

    error C267: 'th_microSecondsNow_2': requires ANSI-style prototype
    

    So I may assume that with a missing prototype during compilation ( but a function present in .o object file letting the linker finish its job ) the function was treated as

    int th_microSecondsNow(void);
    

    As int on the C51 compiler is a 16 bit, and plain int always signed, it may explain the odd behaviour we had.

Reply
  • Another step towards understanding of the problem.

    The header file containing the function th_microSecondsNow() was missing.

    So the prototype ( u32 th_microSecondsNow(void); )was missing but the compiler did not complain unless with a warning

    warning C206: 'th_microSecondsNow': missing function-prototype
    

    Naturally during first steps of development the number of warning is huge and this one was completely lost among the others

    As I had tried to introduce a new function:

    void th_microSecondsNow_2(u32 * ptr);
    


    I obtained an error. Why a warning in one case and an error in the other case, while the 2 functions are written one just below the other ??

    error C267: 'th_microSecondsNow_2': requires ANSI-style prototype
    

    So I may assume that with a missing prototype during compilation ( but a function present in .o object file letting the linker finish its job ) the function was treated as

    int th_microSecondsNow(void);
    

    As int on the C51 compiler is a 16 bit, and plain int always signed, it may explain the odd behaviour we had.

Children
  • Naturally during first steps of development the number of warning is huge and this one was completely lost among the others

    I would disagree with the assumption that you might expect a huge number of warnings during the first steps of a developments.

    A sensible approach is to always treat warnings as errors until or unless you can prove otherwise.

  • Traditional C assumes that functions takes int parameters and returns int. And that variables without a type is int.

    And this will result in big problems when you have an 8-bit processor with 16-bit int and a function that returns 32-bit unsigned.

    This is a reason why using C++ (even for C-style programs) makes C++ a better C. Type-safe linking makes sure that you don't accidentally call a function with wrong parameter or return type.

    I'm not sure exactly what makes the compiler decide that the uint32 pointer parameter of the second function should be giving an error while the other function without parameters should just result in a warning. Best is if the compiler is configured to upgrade all warnings about missing prototypes into full errors to avoid producing programs that looks like they should work but secretly produces broken results.

  • "I would disagree with the assumption that you might expect a huge number of warnings during the first steps of a developments."

    I prefer iterative development, where new code is added, compiled and tested in small blocks. And warnings getting caught and analyzed as they show up. So never any large numbers of warnings. But sometimes a large number of errors, because of some syntax error.

    It's best to take care of any warnings immediately, while the relevant code lines are in fresh memory. And preferably before the code is module-tested, to make sure that a late change doesn't break the code.

  • So the prototype ( u32 th_microSecondsNow(void); )was missing but the compiler did not complain unless with a warning

    warning C206: 'th_microSecondsNow': missing function-prototype
    Naturally during first steps of development the number of warning is huge and this one was completely lost among the others

    'naturally' before you start anything else you get rid of all warnings

  • I agree with you all.
    It is however explicitely written in the coding guidelines of every company, the langage be C, C++, VHDL or whatever you have.
    Anyway I am using generated code and at the present time losts of warnings can not be avoided or quickly fixed.

  • It is however explicitely written in the coding guidelines of every company,
    I know of no company with a "coding guideline" that accept a lot of warnings. I know of a case where you had to justify each and every warning you wanted to temporarily live with and more cases where warnings just were not accepted.

    Anyway I am using generated code and at the present time losts of warnings can not be avoided or quickly fixed.

    1) what do you mean by 'generated code'
    2) if you can not fix warnings, you are lost anyhow

  • 1) what do you mean by 'generated code'
    Excel based code generation, MATLAB model based code generation which always gives QAC warnings, compiler warnings in first time integration. Single C file is auto generated based on configuration. File may be large which resulted many warnings or may be migrated to another platform.

    But for this kind of auto generated code we can not generate block by block or partial to test with your module as far as i know.