1

I'm wondering if it can be written that the prepocessor evaluates assigned constants known at compile time and returns the result as a string. I believe the answer is no or complex, but I'll give a try.

Basically I have constants which are expressed in milliseconds but I want to display the results as secs, therefore divide by 1000, and wonder because all is known at compile time, if the preprocessor can directly put the result of this division into the code rather than eval at runtime.

Example:

#define FREQ_AUTO_WHEN_RELAY_ON 150000UL

#define STR_HELPER(x) #x

#define STR(x) STR_HELPER(x)

STR( FREQ_AUTO_WHEN_RELAY_ON/1000UL ) " secs"

would yield to "150000UL/1000UL secs"

which is not I want to display, aka "150 secs"

Thanks

user2718593
  • 111
  • 8
  • Because STR makes a string out of it. Try `printf( "%d secs", FREQ_AUTO_WHEN_RELAY_ON / 1000UL)` instead. – fishinear Feb 05 '23 at 13:10
  • This is what I try to avoid, by means of preprocessor statements. – user2718593 Feb 05 '23 at 14:21
  • I think Boost has a CPP math header, but IDK if you can get the result as a string. It might just construct expressions. – Peter Cordes Feb 05 '23 at 17:27
  • 1
    You can potentially get a *compile*-time constant array of chars or maybe a C++ `std::string`, but probably not a string *literal* from the C preprocessor alone. e.g. stuff like [Is it possible to generate a string at compile time?](https://stackoverflow.com/q/24566547) / [Convert a number to a string literal with constexpr](https://stackoverflow.com/a/24000041) or [How to create compile-time constant string with prepended length byte?](https://stackoverflow.com/q/65204945) or [Creating a compile time string repeating a char n times](https://stackoverflow.com/q/68286513) – Peter Cordes Feb 05 '23 at 20:20
  • [C++ convert integer to string at compile time](https://stackoverflow.com/q/6713420) links to some C++17 `constexpr` code on github. Of course that's not the C preprocessor, so it won't work if you need this as truly part of a string literal, like for an `asm("")` statement. Or if you need it for C rather than C++. – Peter Cordes Feb 05 '23 at 20:25

1 Answers1

1

You have to first prepare a header with all possible outputs:

// calculate.h
#if VALUE == 1
#define RESULT  1
#elif VALUE == 2
#define RESULT  2
/* etc. millions of lines */
#elif VALUE == 150
#define RESULT  150
#endif

Then you can do:

#define VALUE  FREQ_AUTO_WHEN_RELAY_ON/1000UL 
#include "calculate.h"
STR(VALUE)

Similarly, you first have to define a matrix of all possible combinations of values:

#define DIV_1UL_1UL  1
#define DIV_1UL_2UL  0
#define DIV_2UL_1UL  2
/* etc. really millions of lines */
#define DIV_150000UL_1000UL  150

Then you can:

#define DIV(a, b)   DIV_##a##_##b
#define XDIV(a, b)  DIV(a, b)
STR(XDIV(FREQ_AUTO_WHEN_RELAY_ON, 1000UL))

Can C-preprocessor can output as a string the evaluation of compiled known constants values(e.g. 150000UL/1000UL)?

Yes, but it's not practical. Instead, generate the header file from a build system.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111