4

I'm doing some microcontroller programming and I have code along these lines:

#define F_CPU 8000000
#define F_ADC (F_CPU / 64.0)
#define T_ADC (1.0/F_ADC)

Is there a way to print out the calculated values of, say T_ADC at compile time? I tried stringifying it

#define STRINGIFY(s) XSTRINGIFY(s)
#define XSTRINGIFY(s) #s
#pragma message ("T_ADC " STRINGIFY(T_ADC)) 

But that just gives the macro-expansion "(1/(8000000/64))", not the actual value.

This being a micro-controller program, it's awkward to do a printf at startup time. I'm using gcc and I'm happy to use any non-standard gcc features if that helps.

Haris
  • 12,120
  • 6
  • 43
  • 70
Fasaxc
  • 756
  • 4
  • 17
  • 2
    I assume you didn't mean to include the `=` signs in the `#define` statements. ;) And, unfortunately, the preprocessor substitutes defines as strings and doesn't compute them. The arithmetic is done by the actual compiler and the results are only in the compiled results. Although I don't know if there's a tool out there somewhere that does the computation. – lurker Sep 15 '13 at 01:56
  • This does not do precisely what you want but if you know at least a couple of combinations of possible post-evaluation values you could try what has been discussed here: http://stackoverflow.com/questions/1560357/can-the-c-preprocessor-perform-integer-arithmetic – Andon M. Coleman Sep 15 '13 at 02:43
  • Fixed the = in the #defines; it's been a while since I wrote any C! (Was trying to make up a simple example on the fly rather than just copy my code in.) – Fasaxc Sep 15 '13 at 04:57
  • for VC++ users, there are VC++ tricks to print compile time constants without relying on compilation error: see my answer here:https://stackoverflow.com/questions/28852574/how-to-print-result-of-a-compile-time-calculation-in-c – JavaMan May 26 '17 at 16:11
  • I solved this by writing a separate .c file meant for the host machine, importing the same .h files, printing the values of the macros (to a .txt file) and then compiling it (using gcc for host) and running it as a post-build step. Then there's a nice summary of the important values that I can commit along with the changes, compare between projects, etc. – endolith Jun 09 '22 at 18:28

3 Answers3

1

As @mbratch and @freddie said, the computation is made by the compiler, so you can not get the result simply using preprocessor directives. The easiest way that comes to mind right now, is to assign the macro to a global const, and then read the value of the const using a debugger, or opening the binary image of the executable (you can get the address of the constant from the memory map file).

const float temp = T_ADC;

Note that you are forced to specify the C type, and this is an essential step since the result of the macro depends on it.

omegatre
  • 178
  • 7
  • This sounds like progress towards my goal, I already switched to const declarations to avoid accidentally comparing with a float #define (and triggering the compiler to insert the floating point engine). – Fasaxc Sep 15 '13 at 22:04
  • but you can get the constant values in an implementation-dependent way; see https://stackoverflow.com/questions/31149454/getting-the-value-of-compile-time-expressions-in-c – Jason S Jun 10 '22 at 13:17
0

I implemented a baud rate calculation in the preprocessor for a microcontroller but tweaked the integer divide so it rounded (as truncation has more error). Then I displayed the achieved error in a series of categories of low, med and too much, but I stopped short of +-X.X% * due to the extra tedious coding effort.

It was along the lines of http://99-bottles-of-beer.net/language-c-c++-preprocessor-115.html but:-

  • tedious to do, as it's proportional to:-
    • the number of digits/categories required
    • the number of variables as nothing can be shared
  • fairly preprocessor specific
  • devoid of any compiler checks

As I don't have the code, the exercise/tediousness is left to the reader...

* Using scaled integer based calculations

chip_wrangler
  • 145
  • 1
  • 4
-1

It's not exactly what you're looking for but it'll help.

/* definition to expand macro then apply to pragma message */
#define VALUE_TO_STRING(x) #x
#define VALUE(x) VALUE_TO_STRING(x)
#define VAR_NAME_VALUE(var) #var "="  VALUE(var)

#define F_CPU  8000000
#define F_ADC  (F_CPU / 64.0)
#define T_ADC  (1.0/F_ADC)

#pragma message VAR_NAME_VALUE(T_ADC) /* prints  note: #pragma message: T_ADC=(1.0/(8000000 / 64.0) */

This is called Stringification.

Edit: The pre-processor only does string replacement. You could use the pragma message and then use a simple script to do the computation. Continued from my comment above.

$ gcc a.c 2> out
$ python -c "print `cat out | cut -d = -f2`"
8e-06
Freddie
  • 871
  • 6
  • 10
  • I don't get really how will it help – Jack Sep 15 '13 at 02:31
  • 2
    He wants to evaluate the pre-processor tokens arithmetically at compile-time, not print them out exactly as they appear. – Andon M. Coleman Sep 15 '13 at 02:35
  • Since the pre-processor only does string replacement, there isn't really a way to print out what they evaluate to. What I was attempting to get at, but apparently completely left out, was that you can then do the calculation on your own outside of the compilation. – Freddie Sep 15 '13 at 15:08