#elseif not working

the people.vcu.edu has the following text in a tutorial on #ifdef:
[If an #ifdef is evaluated to be false, then the #elseif directive is processed as if it was an #ifdef directive.

However, I'm getting an error that says (in the code line that says "#elif _RADIANT") "#elif with no expression"

in declarations I have the following:
    // Pick one unit from 6 below (LIGHT units in a separate file)
    // #define _SHOP    // nanoB PCB, this has the only RTC, bus master
    // #define _OFFICE  // _MINI PCB
     #define _RADIANT // _nanoB
    // #define _BATH    // _MINI PCB
    // #define _PAINT   // _MINI PCB
    // #define _WATER   // _MINI PCB
    // #define _GARAGE  // nanoB PCB
some code in setup()
end setup()

Then some code in loop
end loop

then I follow all that with functions, which includes the following directives within a function:
#ifdef _BATH
  code specific to Bath
#elif _GARAGE
  code specific to Garage
#elif _RADIANT
code specific to Radiant
#else  // all units with heat (shop, office, paint)
  alternate code
#endif

I've seen various errors when using the #elif/#elseif directive and sometimes they go away when I use one versus the other.

Previously I have only used the #ifdef/#endif pair of directives and everything seems to work, eg, if I have two blocks of code

#ifdef _PAINT
code
#endif

#ifdef _OFFICE
code
#endif

and I define _PAINT and comment out _OFFICE, I get the paint code and no error regarding the office block. I really don't know what "define" does--does it make the following statement a boolean and define it as true? If so, why doesn't the use of an undefined string later in the code not generate an error for an unknown variable?

Yes, I want it to process that line like an #ifdef, per the instructional text quoted above and repeated here:

If an #ifdef is evaluated to be false, then the #elseif directive is processed as if it was an #ifdef directive.

If this reference is incorrect, is there a way to do an if, elseif, elseif, else, endif sequence of directives for the preprocessor? OK, yes, there is a way, but is there a way using "define" to define the test(s)?

I suppose I could do the following:
bool _PAINT = false ;
bool _OFFICE = false ;
bool _GARAGE = false

and then change false for true for the particular compilation/upload that I'm doing? So the code would look something like

#if _PAINT // where _PAINT has been changed to "true" prior to compilation
code
#elif _GARAGE
code
#else // code for all the other units
code
#endif

The full page where I found the tutorial is here.

Thanks.

  1. From that same link above:

#define TEST1 100 // define a variable.
#define TEST2

So this throws me. TEST1 is "defined" as a variable, presumably = 100. What is TEST2? A boolean?

  1. If I do the following and comment out the define TEST2:

#define TEST1 100 // define a variable.
// #define TEST2

and I later use:
#elif TEST2

Why doesn't the IDE throw an error?

Thanks.

You’re almost there...
In the last example TEST2 is either #defined or NOT (i.e. empty)
Yes - a boolean in effect for the preprocessor.
Your previous example could also be explored...

bool _PAINT = true ;
bool _OFFICE = false ;
bool _GARAGE = false

could be reconsidered as-

#define _PAINT
//#define _OFFICE
//#define _GARAGE]
to get the pre-processordoing what you want.
Remembering of course these are not ‘variables’, but macro definitions which are considered by the compiler, not by the program at runtime.

If an #ifdef is evaluated to be false, then the #elseif directive is processed as if it was an #ifdef directive

I don't believe that that's true. The "#elseif" always behaves like "#if", which means that if you want to check whether a symbol has been defined or not, you need:

#elseif defined(_GARAGE)

"#ifdef X" is equivalent to "#if defined(X)", it doesn't have any magical properties on following "#elseif" statements.

"#elseif GARAGE", if GARAGE is not defined, is expanded to just "#elseif ", which is missing an expression, exactly as your error message says...

Thanks to both of you. Getting to understand the higher level directives of the compiler is the key for me and it won't happen overnight--I'll get the macros on by one. Both of your examples make sense and won't be a problem to implement in the code I'm working on (about 2500 lines, so far).

I don't know if it's worth making the point to the author of the "instruction", which I was relying on, and getting his/her error corrected.

Dr Quark

That tutorial looks like it is for a custom preprocessor that the author had written, NOT for the standard C/C++ preprocessor!

Yup. "dcomment".

Thanks. Just one more sand trap to look out for.

DQ

well, I've gotten back to this piece of code and using defined() doesn't seem to work. Here's the code:

#ifdef _SHOP
char board[] = "def: SHOP     " ;
const byte UID = 0x81 ;
#elseif defined(_OFFICE)
char board[] = "def: OFFICE  " ;
const byte UID = 0x82 ;
#elseif defined(_BATH)
char board[] = "def: BATH     " ;
const byte UID = 0x83 ;
#elseif defined(_PAINT)
char board[] = "def: PAINT     " ;
const byte UID = 0x84 ;
#elseif defined(_RADIANT)
char board[] = "def: RADIANT     " ;
const byte UID = 0x85 ;
#elseif defined(_WATER)
char board[] = "def: WATER     " ;
const byte UID = 0x86 ;
#elseif defined(_GARAGE)
char board[] = "def: GARAGE     " ;
const byte UID = 0x87 ;
#endif

If I define _SHOP I get error messages for all the #elseif's

02-bath_office:57:2: error: invalid preprocessing directive #elseif

 #elseif defined(_OFFICE)

and if I define _PAINT, get "board[]" unknown errors.

invalid preprocessing directive #elseif

Try #elif

thanks. I'll give it a try. I was relying on the statement:

The #elif is functionally equivalent to the #elseif directive. These directives are interchangeable.

from the following website:

on edit
!! #elif solved the error. Thanks

Dr_Quark:
from the following website:

More dcomment.