Indexing defines with For loop

Discussion in 'Programmer's Corner' started by bassplayer142, Aug 6, 2012.

  1. bassplayer142

    Thread Starter Active Member

    Jan 2, 2007
    89
    0
    I'm having trouble with an implementation of defines for reading a port pin. The code is below.

    Code ( (Unknown Language)):
    1.  
    2. #define        TACT0STAT    (PINB & 0x01)        //Tact1 Status
    3. #define        TACT1STAT    (PINB & 0x02)        //Tact2 Status    
    4. #define        TACT2STAT    (PINB & 0x04)        //Tact3 Status
    5. #define        TACT3STAT    (PINB & 0x08)        //Tact4 Status
    6. #define        TACT4STAT    (PINC & 0x40)        //Tact5 Status
    7. #define        TACT5STAT    (PINC & 0x80)        //Tact6 Status
    8. #define        TACT6STAT    0x00                //Dummy Status
    9. #define        TACT7STAT    0x00                //Dummy Status
    10.  
    11. #define        TACTSTAT(a)    TACT##a##STAT
    12.  
    13.  
    14. for(int i = 0; i < 8; i++)
    15. {
    16. if(TACTSTAT(i))
    17.     {
    18.         //
    19.     }    
    20. }
    21.  
    When I attempt to compile this I get an error as follows.


    ../main_ATmega644P.c:287:1: error: 'TACTiSTAT' undeclared (first use in this function)

    Does anyone know how to index those defines with the for loop? I would try another method if there is one, but I can't find one.

    Thank you for any help!
     
    Last edited by a moderator: Aug 7, 2012
  2. sbixby

    Active Member

    May 8, 2010
    57
    10
    Unless I'm missing some newfangled technology in C/C++ from recently...

    A define macro only evaluates at *compile time*. You won't get run-time indexing out of your construct. In your case it evaluates the 'i' directly into the define, giving you the unknown "TACTiSTAT".

    The correct way to do it is to create an array and fill it with the values, and index on that instead.
     
    bassplayer142 likes this.
  3. osx-addict

    Member

    Feb 9, 2012
    122
    9
    sbixby is correct.. You're mixing compile time/runtime stuff -- can't do that.. Anything with #define is compile time.. But the for loop is run-time only.. So, you get exactly what you asked for -- TACTiSTAT.. You'll need to convert that last define #TACTSTAT(a) to a real function to get the behavior that you seek..
     
    bassplayer142 likes this.
  4. WBahn

    Moderator

    Mar 31, 2012
    17,775
    4,804
    It's even a bit worse than that. Anything with a # is a preprocessor directive and the compiler never see it. The preprocessor has to resolve all of those before sending it on to the compiler itself. In most cases, including this one, the distinction is pretty moot. But there are some times when it is handy to be aware of it.
     
    bassplayer142 likes this.
  5. bassplayer142

    Thread Starter Active Member

    Jan 2, 2007
    89
    0
    Thanks all! I never liked defines anyway ;)
     
  6. sbixby

    Active Member

    May 8, 2010
    57
    10
    Defines are actually pretty great; with large code it's a good way to specify constant values, so if you use a Define consistently in your code, there will be only the one place to change it if you need to change it. I wouldn't give up on pure defines at all! (One often-repeated old-salt mantra is to never use constant values within the code - always use defines; but I personally think that's overkill, there's always a good balance.)

    The preprocessor macros are also great - but as you found out, they can be both powerful and drive you nuts, too often at the same time.

    WBahn's reminder about pre-processing triggered some memories. I haven't done C/C++ in any measurable way for a good 15 years. I'm a modern-day Java/C# pro now, and frankly, I'd really hate to revert back to C for a typical modern GUI application.

    I'm still new-ish to microcontrollers, but from what I've seen and from what I remember of using C extensively years ago, it's about the best possible combination of usability, maintainability, machine code size and speed as you can get for the limited memory space & performance of a microcontroller.

    I'd have to go back another 10 years to recall my assembler days, something I actually do remember fondly, but I'm sure I won't be fond for long if I start using it again. :)
     
  7. WBahn

    Moderator

    Mar 31, 2012
    17,775
    4,804
    #defines are extremely useful, as are the other preprocessor directives. But just like the tools in a woodshop, they each serve different purposes and while several tools can be used to accomplish most taskes, there are usually one or two tools that are the standout favorites. The most you know how to use all of the tools available to you, the better equipped you will be to use the right tool, and use it the right way, in a given situation.
     
Loading...