views:

77

answers:

3

I want to have a C preprocessor macro that knows the number of instantiations/macro calls of this macro so far. Example:

int main() {
  printf("%d\n", MACRO());
  printf("%d\n", MACRO());
}

Should print

0
1

Is something like this possible?

Note that it is not enough to forward this to a function as proposed below. It should work in the following context:

// global variable
std::vector<bool> calls_hit;

#define OTHER_MACRO() \
{ \
    const int counter = MACRO(); \
    calls_hit.resize(std::max(calls_hit.size(), counter)); \
    calls_hit[counter] = true; \
}
+6  A: 

Why must this be a macro? Anyway, you can just wrap a function with a static counter in a macro:

int count_calls() {
    static count = 0;
    return count++;
}

#define MACRO() count_calls()
Konrad Rudolph
what if the function gets called from outside the macro ?...
Andy
@Andy: well then of course the count gets incremented as well.
Konrad Rudolph
No, this does not work. I want to have the number of calls at compile time.
Manuel
@Manuel: if you want the number of calls at compile time you'll have to use something like `__COUNTER__` with a macro to wrap calls to the function your targeting, however, that means you can't use `__COUNTER__` for anything else...
Necrolis
@Manuel: can’t be done with macros. Template metaprogramming might be of help, but then you need to give more detail. In particular, my solution still works with the new code you’ve posted in the question; no compile-time knowledge is necessary.
Konrad Rudolph
A: 
#define MACRO() (stupid_macro_counter++)
int stupid_macro_counter = 0;
PigBen
I'd strongly prefer Konrad's solution over this one.
sbi
@sbi -- That's fine, but could you elucidate on why?
PigBen
@PigBen: Because this one needs a variable with arbitrary global scope, while Konrad's avoids that.
sbi
A: 

What's wrong with

// global variable
std::vector<bool> calls_hit;

inline void a_function_since_this_is_not_C_after_all()
{
  static unsigned int hits = 0;
  const int counter = hits++;
  calls_hit.resize(std::max(calls_hit.size(), counter));
  calls_hit[counter] = true;
}
sbi