0

I have a following input file:

#define __SIZE_K(x) (x * 1024)
#define DT_FLASH_SIZE       __SIZE_K(128)
reg = <0x08000000 DT_FLASH_SIZE>;

If I run that through a preprocessor I get this:

$ cpp -x assembler-with-cpp input.dts -E -P
reg = <0x08000000 (128 * 1024)>;

If it possible to get the macro fully evaluated? I would like to have:

reg = <0x08000000 131072>;

I would like to have devicetree source files "fully-preprocessed" and I would prefer to do this entirely in the preprocessor, but I'm not sure this is possible... The final devicetree consists of multiple files, some of which define the layout, some are headers with macros and various values depending on selected chip.

Progman
  • 16,827
  • 6
  • 33
  • 48
Freddie Chopin
  • 8,440
  • 2
  • 28
  • 58
  • Possible duplicate of http://stackoverflow.com/questions/40470723/is-it-possible-to-make-integer-math-with-c-preprocessor – Yunnosch Apr 15 '17 at 06:22
  • Another related one: http://stackoverflow.com/questions/1560357/can-the-c-preprocessor-perform-integer-arithmetic So generally, it is possible, but very complicated (and not what the preprocessor was designed for) – chtz Apr 15 '17 at 07:32
  • Possible duplicate of [Can the C preprocessor perform integer arithmetic?](http://stackoverflow.com/questions/1560357/can-the-c-preprocessor-perform-integer-arithmetic) – Yunnosch Apr 19 '17 at 06:04
  • The preprocessor is for text replacement, and has no arithmetic logic. However, the compiler does, so, the `128 * 1024` will be evaluated to `131072` before the executable is made. If you want it to be done in the preprocessor to speed up compilation - the reason that the preprocessor is fast is because it's simple and so isn't able to handle this kind of thing; if it could, it'd be slower. – Elliott Dec 26 '21 at 00:48

1 Answers1

1

If it possible to get the macro fully evaluated?

Theoretically, yes. But it's not usable in the context you want to use it.

Preprocessor is a simple text replacement tool. It replaces one text for the other. First, you have to implement a table of all possible combinations of replacements:

#define MUL_1_1     1
#define MUL_1_2     2
#define MUL_1_3     3
// etc. for **billions** of lines
#define MUL_128_1024   the_result_here
// etc.

After those bilions of lines, you can finally write:

#define MUL_(a, b)  MUL_##a##_##b
#define MUL(a, b)   MUL_(a, b)

After that you can do:

#define __SIZE_K(x) MUL(x, 1024)

You can use a library - like P99_MUL or BOOST_PP_MUL - and they are basically implemented in almost the same way, with a lot of optimizations to shorten the list.

There is no point in using specifically C preprocessor in this context anyway. Use M4 or Python's Jinja2 or PHP - a full programming language, instead of some limited preprocessing C tool.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111