#if preprocessor not evaluated correctly

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Using studio6/avr-gcc the preprocessors are not evaluated correctly.

Line 5 below is always evaluated TRUE and thus USE_SPI is always set.

Is there a flag needed to be set to have avr-gcc evaluate preprocessors? Any help appreciated.

1: enum BUILD_VARIANTS {BUILDVAR_1, BUILDVAR_2, BUILDVAR_3};
2: #define BUILD_VARIANT BUILDVAR_1
3: 
4: // Configuration based on build-variant
5: #if BUILD_VARIANT == BUILDVAR_2
6:   #define USE_SPI                             1
7: #endif

 

Breg

 

Regards
Vidar (Z)

----------------------------------------------------------

"The fool wonders, the wise man asks"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The preprocessor doesn't understand enum

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

f...

Regards
Vidar (Z)

----------------------------------------------------------

"The fool wonders, the wise man asks"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Besides, what's the advantage of what you have there over:

2: #define BUILD_VARIANT 2
3: 
4: // Configuration based on build-variant
5: #if BUILD_VARIANT == 2
6:   #define USE_SPI                             1
7: #endif

 

The largest known prime number: 282589933-1

It's easy to stop breaking the 10th commandment! Break the 8th instead. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My code was just a simplified example stripped down to least non working code. My code is written to be used on several diferent HW, and each HW may also come in diferent flavours therefor it is nice to have a set of definitions wich represents each possible variants in an easy to understand textual description and which BUILD_VARIANT is set to.

 

My real code have many #if / #elif which configures the code. There is also a string which will be sent to an master over uart based on the BUILD_VARIANT

 

Its more like this (whitout enum but using defines instead)

#define HW_THIS_AND_THAT_VARIANT1 0
#define HW_THIS_AND_THAT_VARIANT2 1
#define HW_ANOTHER_THIS_AND_THAT_VARIANT1 2
#define HW_ANOTHER_THIS_AND_THAT_VARIANT2 3

#define BUILD_VARIANT HW_ANOTHER_THIS_AND_THAT_VARIANT1

// Then testing and enabling/disabling code and peripherals based on BUILD_VARIANT. And so on

 

 

 

Regards
Vidar (Z)

----------------------------------------------------------

"The fool wonders, the wise man asks"

Last Edited: Wed. Oct 1, 2014 - 03:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This bit me recently. I had a contiguous set of macros defined with #define, and I used those macros in preprocessor statements in other parts of the code to control which parts get compiled. I wanted to clean up the code so I converted the #define's to an enum, and then I found that my code was not building as I expected! I changed them back to #define's and it worked again. (Eventually I'd like to change my code so it doesn't depend as much on the preprocessor so it can decide what to do at runtime, and also reduce the number of configurations I have to build, but that's presently not the case.)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can probably make all your variants depend on one #define.

After all,   a 32-bit number gives you 4000M variants.

In practice,   you probably use less than 32 on-off options.

 

Just sit down with your current conditionals and tidy them up.

And decide which might be 'runtime' options.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Basics of the C preprocessor (CPP):

 

CPP runs before the compiler proper. CPP knows nothing about the C language. CPP is a text processing thing. It identifies things starting with a hash-sign (#) and acts on those.

 

A #define creates an entry in the CPP symbol table - each entry being a mapping from one text (symbol) to another (definition). Whenever the symbol then is encountered in the source code it is replaced by the definition. It is pure textual substitution.

 

A #include is replaced by the contents of the file #include'd.

 

For #ifdef the text between #ifdef and #endif is kept intact (and also preprocessed!) if the symbol in the #ifdef is in the CPP symbol table. Else the whole text block is simply removed, and the compiler will never see it.

 

Similar for #if, but the symbol is tested for a specific value.

 

All this is done before the compiler proper has started. All this is done without any knowledge at all about the C language. There are no known types. No known language constructs (in this case enum's specifically). The only "language" known is the CPP language itself. Everything else is just text.

 

You could use the CPP to mangle any text you wish. If you had the complete text of Don Quixote in text file format you could use CPP and two #defines to get a story about Laurel and Hardy.

 

The CPP is not a part of the C language. Understanding this is key to using the CPP.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Thu. Oct 2, 2014 - 07:38 AM