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

Macro define vs var data type

Hi,
I'm just curios on how this work.
Is this a general C/C++ process or C51?

In main.h, I have a:

#define MAX_TIME_OUT      3000         //This is beyond U8

In Worker.c, I have Timer 2 ISR:

#include "main.h"

U8 _temp_cntr;                          //unsigned char and not initialized

//T2 init here

void T2_ISR() interrupt using 0
{
   //some flag being set here

   _temp_cntr++;                        //Should this be back to 0 when reach 255?
   if(_temp_cntr == MAX_TIME_OUT)       //What will happen here?
   {
       _temp_cntr = 0;
   }
}

Hope somebody can enlighten me on this.
My UART1 on F387 mcu won't able to run when Timer 2 ISR is enabled because of the specific condition under the ISR.

thanks
gp

  • Yes - a 'C' textbook will enlighten you!

    'C' has standard, defined ways to cope with this situation.

  • Have you checked the meaning of your U8 data type.

    Do you see any problem with comparing the value of that parameter with the value 3000? Can the variable even store the value 3000?

  • Hi Per,
    Thanks for your reply.

    Yes, its U8 = unsigned char, 1byte size.
    My first thought was:

    _temp_cntr++;
    if(_temp_cntr == MAX_TIME_OUT) //_temp_cntr will not store the value 3000. Only to compare with MAX_TIME_OUT
    

    _temp_cntr can't reach 3000, and so there is no way it would be equal with MAX_TIME_OUT.

    Can you explain more about your last question? Im sure you are referring to the variable _temp_cntr which is U8.

    My question, will the MAX_TIME_OUT automatically set its data type during compile time?
    If yes, is it a signed int or unsigned int?

    The C51 and the Microsoft C compiler accepted the comparison during compile time, but some code is affected during runtime.

    I've read some books, it has to do with conversion and ranking.
    Assuming C51 relies C99 standard, my U8 variable then converted to a signed int if MAX_TIME_OUT data type is signed int during compile time.
    If _temp_cntr reaches 255 for example, it became 0x00ff and roll back to 0x0000.

    But still confuse why it runs without errors however some part of the code get affected during runtime.

    thanks
    gp

  • Never assume - always specifically check the documentation:

    http://www.keil.com/product/isoansi.asp

    http://www.keil.com/support/man/docs/c51/c51_xa.htm

    "The C51 and the Microsoft C compiler accepted the comparison during compile time..."

    There is nothing wrong with the syntax - so you will, obviously, get no syntax errors from the compilers!

    "...but some code is affected during runtime"

    The code will operate as defined by the 'C' language standard - so you need a proper understanding of the 'C' language in order to have a valid expectation of what the code will do!

    Again, a 'C' textbook will explain the standard processes that are used for conversions between different data types; eg, publications.gbdirect.co.uk/.../expressions_and_arithmetic.html

  • No, #define doesn't have any data type.

    It isn't really part of the C language, even if it is part of the C language standard. There are almost no rules about what you can write after the symbol name (you have a few operators like # and ##, and it knows that when removing comments it has to insert some whitespace instead of the comment).

    #defines are just an advanced search/replace functionality in the language.

    So when the compiler is ready to generate code, it does not process

    if (var == def) ...
    


    but instead

    if (var == expansion) ...
    

    Your code is then:

    if (_temp_cntr == 3000) ...
    

    If _tmp_cntr can never store a value larger than 255 without rolling back to the value zero, you can continue to increment, and increment and increment until you get a power failure. The if statement will still never be true. Some compilers will - if full warnings are enabled - add an explicit warning about impossible numeric-range comparisons.

  • Thank you guys for the help, your time and for the well explained explanation.

    thanks
    gp

  • " if(_temp_cntr == MAX_TIME_OUT) //What will happen here?"

    it will simple give promote both types to integer and then perform the comparison which will never be true.

    but actual compilers may not perform always as expected by the rules.

  • If code below is missing, it would cause timer 2 interrupts non-stop affecting system operation: TF2 = 0;

    Also, it could be a good idea to declare the variable as volatile if it is also accessed in the main program.