Jump to content

Preprocessing Error - Macro

Recommended Posts

The macro is intended to set a predefined bit of a particular variable, instead of have to remember the names all the time, nothing much about it, but by question is about macro sintax.


When i try to compile a code with the macro shown below, it gives me a preprocessor error in the "SetSystemFlag" macro definition.


"error: preprocessing error"

"main.h(line_number): Illegal or out of token: |"


<<< compiler version 7.30 >>>

/*** main.h ***/

extern unsigned char sysflags;
#define SYS_FLAG 1
#define SetSystemFlag( sysflags |= ( 1 << SYS_FLAG ))  // <<< preprocessing error

/*** main.c ***/
// includes, etc

void main( void )

Looks like the preprocessor likes to be at least one space character between the token "SetSystemFlag" and the parenthesis as shown below. It give me no errors if i do it with a space char.

#define SetSystemFlag ( sysflags &= ( 1 << SYS_FLAG ))
//                   ^
//                    \___ space character to avoid preprocessor error

My question is if this "space" is an ansi rule or a minor bug because reading about it i didn't see any reference to impose this space character.



Edited by joli
Link to post
Share on other sites



I think you are mixing the "C pre-processor" with the "C language".


The "C language" syntax doesn't require any kind of "white space" separators, not even line changes.

But the "C pre-processor" has a different set of rules.

That space character or any other form of "white space" is needed to separate the "name" and the "content".

Keep in mind that the "C pre-processor" is nothing more than an enhanced text search and replace. So there the need to clearly separate the "search" from the "replace" strings.


In fact, is generally accepted as good practice to use one or more "tab" characters separating the macro designator (name) and its contents in a way that the source code looks like written in columns.


here is a snipset of one of my projects that ilustartes how I do it.


// ---------
// ---------
// Using PIC16 compatible mode (no priorities) - default mode after a power on reset
// Macros for interrupt operation
//Timer 0 interrupt control
#define Enable_Tmr0_Int() {clear_bit(intcon,TMR0IF); set_bit(intcon,TMR0IE);}
#define Disable_Tmr0_Int() {clear_bit(intcon,TMR0IE);}
// ADC interrupt control
#define Enable_ADC_Int() {clear_bit(pir1,ADIF); set_bit(intcon,PEIE); set_bit(pie1,ADIE);}
#define Disable_ADC_Int() {clear_bit(pie1,ADIE);}
// MSSP1 interrupt control
#define MSSP1_Intr_Enable() {clear_bit(pir1,SSP1IF); set_bit(pie1,SSP1IE); set_bit(intcon, PEIE);}
#define MSSP1_Intr_Disable() {clear_bit(pie1,SSP1IE);}
// Global interrupts control
#define Enable_Interrupts() {set_bit(intcon,GIE);}
#define Disable_Interrupts() {clear_bit(intcon,GIE);}





Best regards


Link to post
Share on other sites

1.4 Symbolic Constants

A final observation before we leave temperature conversion forever. It's bad practice to bury
``magic numbers'' like 300 and 20 in a program; they convey little information to someone
who might have to read the program later, and they are hard to change in a systematic way.
One way to deal with magic numbers is to give them meaningful names. A #define line
defines a symbolic name or symbolic constant to be a particular string of characters:

#define name replacement list

Thereafter, any occurrence of name (not in quotes and not part of another name) will be
replaced by the corresponding replacement text. The name has the same form as a variable
name: a sequence of letters and digits that begins with a letter. The replacement text can be
any sequence of characters; it is not limited to numbers.

#include <stdio.h>
#define LOWER 0 /* lower limit of table */
#define UPPER 300 /* upper limit */
#define STEP 20 /* step size */
/* print Fahrenheit-Celsius table */
int fahr;
for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP)
printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));

The quantities LOWER, UPPER and STEP are symbolic constants, not variables, so they do not
appear in declarations. Symbolic constant names are conventionally written in upper case so
they can ber readily distinguished from lower case variable names. Notice that there is no
semicolon at the end of a #define line.

Text from K&R second edition.






Link to post
Share on other sites



I saw where my mistake was, the first parenthesis of arguments section should be placed near to the macro name with no space between, but the "code section" should have at least one space.


So i change it to:

#define SetSystemFlag() ( sysflags |= ( 1 << SYS_FLAG )) 

I may use this too:

#define SetSystemFlag ( sysflags |= ( 1 << SYS_FLAG )) 



Completly agreed with those principles that you mentioned.


It's a good thing to put here such explanations.


ty both


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...