5

My code is

#define PASTE__(a, b) a##b
#define PASTE_(a, b)  PASTE__(a, b)
#define PASTE(a, b) PASTE_(a, b)

int main()
{
    PASTE(1, (1+3)/4);
    return 0;
}

I would LIKE to have the result be

int main()
{
    11;
    return 0;
}

Compilable link: http://coliru.stacked-crooked.com/a/b35ea3e35a1b56ae

I put in two levels of indirection suggested by How can I guarantee full macro expansion of a parameter before paste?.

But still I get a preprocessor error:

main.c:8:11: error: pasting "1" and "(" does not give a valid preprocessing token
     PASTE(1, (1+3)/4);
           ^
main.c:1:23: note: in definition of macro 'PASTE__'
 #define PASTE__(a, b) a##b
                       ^
main.c:3:21: note: in expansion of macro 'PASTE_'
 #define PASTE(a, b) PASTE_(a, b)
                     ^
main.c:8:5: note: in expansion of macro 'PASTE'
     PASTE(1, (1+3)/4);

How do I get the preprocessor to resolve the result of that expression before doing concatenation?

Community
  • 1
  • 1
Bob
  • 4,576
  • 7
  • 39
  • 107

2 Answers2

4

It looks like you're trying to get the preprocessor to evaluate some simple mathematical operations and convert to the result. This is not possible without substantial extra macro infrastructure to perform the necessary math. The easiest way to get the needed infrastructure is probably to use BOOST_PP.

http://www.boost.org/doc/libs/1_59_0/libs/preprocessor/doc/index.html

You would need to modify your code so that macros are used to perform the math rather than operators. The line in question would look like:

PASTE(1, BOOST_PP_DIV(BOOST_PP_ADD(1,3),4));

Now the answer would come out as 11, and I assume that's what you're looking for.

Charles Ofria
  • 1,936
  • 12
  • 24
  • If I were using C++, it'd definitely be useful. – Bob Oct 28 '15 at 21:37
  • 4
    "The Boost Preprocessing library is a library of macros, with support for preprocessor metaprogramming. **The library supports both C++ and C compilation. It does not depend on any other Boost libraries and therefore may be used as a standalone library**" - http://www.boost.org/doc/libs/1_59_0/libs/preprocessor/doc/index.html – Michael Burr Oct 28 '15 at 21:41
  • 1
    I have tested this in a C program and it works perfectly. – Michael Burr Oct 28 '15 at 21:52
  • I switched the "answer" @MichaelBurr – Bob Oct 29 '15 at 20:45
0

What exactly are you hoping the preprocessor output for the PASTE line will be? 11;? That's impossible. (update: apparently it is possible with clever enough macros. See Charles Ofria's answer).

That double-expansion with multiple macros is only useful for expanding macros and then stringifying the results, IIRC.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • @Adrian: turns out I was wrong, and this is possible. You should mark Charles's answer as correct. – Peter Cordes Oct 29 '15 at 02:59
  • Ok I did. But still gave you upvote because in my case, using Boost won't be accepted by peers - embedded in automotive industry - so knowing that preprocessor doesn't evaluate expression DIRECTLY is still useful information. I'm gonna use Python to pre-preprocess my .c files. – Bob Oct 29 '15 at 20:43
  • @Adrian: As long as you only use pre-processor boost library, and not any other part of Boost, it can't bloat your code (unless you use it to generate bloated code, which this case doesn't do). After pre-processing, the compiler will still see an `11`. If you can't add a dependency on the Boost header, then sure, work around it. – Peter Cordes Oct 30 '15 at 16:07
  • Oh I know it won't bloat it. But you've never worked in automotive: if I say 'I got it from the internet' everyone freaks. – Bob Oct 30 '15 at 19:41
  • 2
    I've reimplimented basic macro math from scratch if you want a set of macros with an explanation for how they work. Then you can just say you got it from a Professor of Computer Science at Michigan State. ;-) – Charles Ofria Oct 31 '15 at 03:09