views:

229

answers:

5

For some base. Base 1 even. Some sort of complex substitution -ing.

Also, and of course, doing this is not a good idea in real life production code. I just asked out of curiosity.

+1  A: 

I'm pretty sure the C/C++ preprocessor just does copy and paste -- it doesn't actually evaluate any expressions. Expression evaluation is done by the compiler.

To better answer your question, you might want to post what you're trying to accomplish.

Victor T.
The preprocessor does perform some expression evaluation. The `#if` and `#elif` directives both take expressions that must be macro replaced and then evaluated to determine whether they evaluate to true or false (or one or zero, in C).
James McNellis
+5  A: 

I know it's not the preprocessor, but if it helps, you can do it with templates. Perhaps you could use this in conjunction with a macro to achieve what you need.

#include <iostream>
using namespace std;

template <int N, int M>
struct Add
{
    static const int Value = N + M;
};

int main()
{
    cout << Add<4, 5>::Value << endl;
    return 0;
}
Chris Schmich
Why not just use `Value = N + M` inside of `Add`?
James McNellis
@James: great point, thanks. I've updated my response.
Chris Schmich
+7  A: 

The preprocessor operates on preprocessing tokens and the only time that it evaluates numbers is during the evaluation of a #if or #elif directive. Other than that, numbers aren't really numbers during preprocessing; they are classified as preprocessing number tokens, which aren't actually numbers.

You could evaluate basic arithmetic using token concatenation:

#define ADD_0_0 0
#define ADD_0_1 1
#define ADD_1_0 1
#define ADD_1_1 2

#define ADD(x, y) ADD##_##x##_##y

ADD(1, 0) // expands to 1
ADD(1, 1) // expands to 2

Really, though, there's no reason to do this, and it would be silly to do so (you'd have to define a huge number of macros for it to be even remotely useful).

It would be more sensible to have a macro that expands to an integral constant expression that can be evaluated by the compiler:

#define ADD(x, y) ((x) + (y))

ADD(1, 1) // expands to ((1) + (1))

The compiler will be able to evaluate the 1 + 1 expression.

James McNellis
I always like to see the ## doing some real work.
Tom
+1  A: 

The C preprocessor can evaluate conditionals containing integer arithmetic. It will not substitute arithmetic expressions and pass the result to the compiler, but the compiler will evaluate arithmetic on compile-time constants and emit the result into the binary, as long as you haven't overloaded the operators being used.

Chris
+1  A: 

Preprocessor macros can't really do arithmetic, but they can be usefully leveraged to do math with enumerations. The general trick is to have a macro which invokes other macros, and can be repeatedly invoked using different definitions of those other macros.

For example, something like:

#define MY_THINGS \
  a_thing(FRED,4) \
  a_thing(GEORGE,6) \
  a_thing(HARRY,5) \
  a_thing(HERMIONE,8) \
  a_thing(RON,3) \
  // This line left blank 

#define a_thing(name,size) EN_##name}; enum {EN_SIZE_##name=(size),EN_BLAH_##name = EN_##name+(size-1),
enum {EN_FIRST_THING=0, MY_THINGS EN_TOTAL_SIZE};
#undef a_thing

That will allow one to 'allocate' a certain amount of space for each thing in e.g. an array. The math isn't done by the preprocessor, but the enumerations are still regarded as compile-time constants.

supercat