Pages: [1]   Go Down
Author Topic: Preprocessor madness  (Read 949 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Many projects must be tested in various configurations requiring different code for each configuration.  The preprocessor should make that simple to accomplish.  However, I believe the mangler is doing something I don't fully understand which makes this code not work.
Code:
/*sketch.pde*/
#define CONFIGURATION TEST_CONFIG_2
#include "config.h"

void setup()
{
int digiPinValue = digitalRead(PREPROC_DEFINED_PIN);
}

void loop()
{

}
Code:
/*
config.h  this file contains conditionally compiled code based on the selected hardware configuration.
*/

#ifndef config_h
  #define config_h 
  #include <stdint.h>
  #if CONFIGURATION == PRODUCTION_READY
    //some pin declarations, includes, code
    //static const uint8_t PREPROC_DEFINED_PIN = 4; //compiles only when PREPROC_DEFINED_PIN is declared here, even though expression is false
   #elif CONFIGURATION == TEST_CONFIG1
    //some pin declarations, includes, code
   #elif CONFIGURATION == TEST_CONFIG2
    //some pin declarations, includes, code 
    static const uint8_t PREPROC_DEFINED_PIN = 4; //compiler complains 'PREPROC_DEFINED_PIN' was not declared in this scope
  #endif /*CONFIGURATION*/ 
#endif /*config_h*/
I've tried adding inert lines to the top of both the sketch and config.h to give the mangler a place to put forward declarations, but to no avail.  I welcome any suggestions for workarounds that do not involve multiple sketches (multiple files within a sketch are ok).  Also, any solution should not require the unused code to be deleted or occupy space on chip.  It would be acceptable to require the user to comment out unused code, however, the IDE has a nasty habit of preprocessing commented code.  That, of course can lead to very unexpected behavior.  I am using Arduino 022, has release 1 addressed these issues?  How do I get a copy?
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8975
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think your problem is that PRODUCTION_READY, TEST_CONFIG1, and  TEST_CONFIG2 are undefined.

Code:
#define CONFIGURATION TEST_CONFIG_2
  #if CONFIGURATION == PRODUCTION_READY

expands to:

Code:
#define CONFIGURATION TEST_CONFIG_2
  #if TEST_CONFIG_2 == PRODUCTION_READY  // Both are undefined and apparently considered to be equal

Perhaps this would work better:

Code:
/*sketch.pde*/
#define TEST_CONFIG_2
#include "config.h"

void setup()
{
int digiPinValue = digitalRead(PREPROC_DEFINED_PIN);
}

void loop()
{

}
Code:
/*
config.h  this file contains conditionally compiled code based on the selected hardware configuration.
*/

#ifndef config_h
  #define config_h 
  #include <stdint.h>
  #if defined(PRODUCTION_READY)
    //some pin declarations, includes, code
    //static const uint8_t PREPROC_DEFINED_PIN = 4; //compiles only when PREPROC_DEFINED_PIN is declared here, even though expression is false
   #elif defined(TEST_CONFIG1)
    //some pin declarations, includes, code
   #elif defined(TEST_CONFIG2)
    //some pin declarations, includes, code 
    static const uint8_t PREPROC_DEFINED_PIN = 4; //compiler complains 'PREPROC_DEFINED_PIN' was not declared in this scope
  #endif /*CONFIGURATION*/ 
#endif /*config_h*/
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Newbie
*
Karma: 1
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you very much for that insight.  I had assumed that since we have tools like #ifdef, #ifndef, #if defined, #if !defined that the question of whether a token is defined was well covered.  So that a line like
Code:
#define CONFIGURATION TEST_CONFIG_2
  #if CONFIGURATION == PRODUCTION_READY
should expand to
Code:
#define CONFIGURATION TEST_CONFIG_2
  #if  TEST_CONFIG_2 == PRODUCTION_READY //evaluated as a string compare.  Strings not equal, thus false.
Which interpretation seems more natural, practical, useful?  If the above code is not a string compare, then how do we use a string compare to evaluate true/false for an #if?  Enclosing in parenthesis seems to have no effect.  What would be the ramifications of modifying the language to act as above?
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8975
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If the above code is not a string compare, then how do we use a string compare to evaluate true/false for an #if? 

You can't.  #if expressions can only work on integer constants and character constants (like 'A'). 

Any undefined symbol evaluates to 0 which is why your two undefined symbols are equal.

Just define all your symbols to be unique integer constants and it should work, or use the method I outlined.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Pages: [1]   Go Up
Jump to: