Preprocessor macro substitutions/calculations

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

I have a question regarding preprocessor directives and when math is done. Is it the preprocessor that does the math in the code, or will gcc take the substituted values and do the math before compiling.

  #define MYVALUE 64

But in my code there are places where I need to alter that value before it's used.

  var_a = (MYVALUE - 1);
  var_b = (MYVALUE - 2);
  var_c = (MYVALUE - 3);

My question is...
Once the preprocessor substitutions are done, will the subtraction need to be performed in code as it's running? Like this...

  var_a = (64 - 1);
  var_b = (64 - 2);
  var_c = (64 - 3);

Or will the preprocessor/compiler do the math before it's compiled, so the code runs as...

  var_a = 63;
  var_b = 62;
  var_c = 61;

Or do I have to define macros for each based on the first, and use them as below...

  #define MYVALUE 64
  #define MYVAL_MINUS1 (MYVALUE - 1)
  #define MYVAL_MINUS2 (MYVALUE - 2)
  #define MYVAL_MINUS3 (MYVALUE - 3)


  var_a = MYVAL_MINUS1;
  var_b = MYVAL_MINUS2;
  var_c = MYVAL_MINUS3;

I'm just trying to avoid using processor cycles unnecessarily.
Thanks, all.

Jim M., Rank amateur AVR guy.

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

Easy to test this by looking at the .i file (avr-gcc with -E rather than -c):

  uint8_t var_a, var_b, var_c;	
	
  var_a = (MYVALUE - 1); 
  var_b = (MYVALUE - 2); 
  var_c = (MYVALUE - 3); 

in .c yields:

  uint8_t var_a, var_b, var_c;

  var_a = (64 - 1);
  var_b = (64 - 2);
  var_c = (64 - 3);

but even if you were mad enough to use -O0 you would still get:

  var_a = (MYVALUE - 1); 
  6a:	8f e3       	ldi	r24, 0x3F	; 63
  6c:	8b 83       	std	Y+3, r24	; 0x03
  var_b = (MYVALUE - 2); 
  6e:	8e e3       	ldi	r24, 0x3E	; 62
  70:	8a 83       	std	Y+2, r24	; 0x02
  var_c = (MYVALUE - 3); 
  72:	8d e3       	ldi	r24, 0x3D	; 61
  74:	89 83       	std	Y+1, r24	; 0x01

in which the 0x3F, 0x3E, 0x3D show that these were calculated at compile time rather than run time - so you don't generate AVR code to do the subtractions whatever -O level you use (and things just get better the higher the level of optimisation you use. At -Os no code is generated whatsoever (because I don't go on to use the var's for anything)

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

That's what I was looking for. The pre-processor does the substitutions, then the compiler does the math so that the variable is simply assigned a number in the code.
Thanks, clawson.

Jim M., Rank amateur AVR guy.

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

If in doubt, do the text substitutions by hand. Look at the expanded expression.

If you can calculate it yourself, so can the compiler.
If it contains any unknown variables, the expression will be calculated at run-time.

The pre-processor does no maths at all in its textual substitutions. '2 + 2' will remain '2 + 2'

However when the pre-processor finds a #if (expression), it will evaluate this (possibly with 64 bit accuracy) e.g. #if ( 2.1 + 2 == 4.1)

David.

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

david.prentice wrote:
However when the pre-processor finds a #if (expression), it will evaluate this (possibly with 64 bit accuracy) e.g. #if ( 2.1 + 2 == 4.1)
Note that there is no guarantee that that expression would be true.
I expect that it usually would, but not necessarily always.

"Demons after money.
Whatever happened to the still beating heart of a virgin?
No one has any standards anymore." -- Giles