paperjam
paperjam

Reputation: 8528

C/C++ macro expanding to argument, argument as string

I have many variables that are named the same as elements in an engineering specification document so the string version of the name is also useful.

I find myself using a macro like this a lot:

#define MACRO(a) a, #a

Typical usage is:

void someFunction(int a, const char *name);

someFunction(MACRO(meaningfully_named_variable));

My question is threefold:

Edit I should have said that the above is a minimal example. The function might have other parameters and the named entity might be a data member or perhaps even a function itself.

Another extension I'm considering for C++ is a class NamedRef that could receive the contents of the macro.

template <typename T>
struct NamedRef
{
    NamedRef(T *t, const char *name) : t(t), name(name) { }
    T *t;
    const char *name;
};

template <typename T>
NamedRef<T> namedRef(T &t, const char *name)
{
    return NamedRef<T>(&t, name);
}

#define WITH_NAME(a) a, #a

// more sophisticated usage example
void otherFunction(double, NamedRef<int>, bool);

otherFunction(0.0, namedRef(object.WITH_NAME(meaningful_member_name)), false);

Upvotes: 9

Views: 3840

Answers (4)

Murali Krishna
Murali Krishna

Reputation: 311

As Jesse answered,

you can write like this:

void function1(int a, const char* name)
{
    cout << "a: " << a << endl;
    cout << "name: " << name << endl;
}

void function2(double d, const char* name, const char *str)
{
    cout << "d: " << d << endl;
    cout << "name: " << name << endl;
    cout << "str: " << str << endl;
}

#define MACRO(functionName, a) functionName(a, #a)
#define MACRO2(functionName, a, ...) functionName(a, #a, __VA_ARGS__)

int main()
{
    int a = 10;
    MACRO(function1, a);
    double d = 10.5;
    MACRO2(function2, d, "Hello world");
    return 0;
}

If you have more arguments to pass, you can use MACRO2 that uses variable arguments. You will have to pass the function name accordingly.

Upvotes: 0

std&#39;&#39;OrgnlDave
std&#39;&#39;OrgnlDave

Reputation: 3968

#define someFunction(a)  if (1) stringized_someFunction((a), #a ); else (void)0
void stringized_someFunction(int a, const char* name);

The if (1) stuff wraps up the macro so that it won't mess (usually) with loops, branches, if statements, etc.

You would then call your function like so:

int r = 4;
someFunction(r);

You only really add one extra line for each "function declaration." If the C preprocessor allowed multiple steps you could wrap it all up into one, but alas, it doesn't.

I forgot because I hope it's obvious that you'd need to write your function:

void stringized_someFunction(int a, const char* name)
{
  // Do stuff here
}

Anyhow it should be a lot easier and prettier to read that way.

Upvotes: 0

EvilTeach
EvilTeach

Reputation: 28882

You are likely to find that XMACROs are useful for this kind of work.

Upvotes: 0

Jesse Good
Jesse Good

Reputation: 52365

You could take it a step further:

#define SOMEFUNCTION(a) somefunction(a, #a)

However, this is only useful if you call the same function alot. Otherwise, I don't think there is any better way than your example. Of course, you should change the name of the macro to something more meaningful though, like ARGUMENTS or something.

Upvotes: 5

Related Questions