How to Generate Random Variable Names in C++ Using MACros

How to generate random variable names in C++ using macros?

Add M4 to your build flow? This macro language has some stateful capabilities, and can successfully be intermingled with CPP macros. This is probably not a standard way to generate unique names in a C environment, though I've been able to sucessfully use it in such a manner.

You probably do not not want random, BTW, based on the way you posed your question. You want unique.

You could use __FILE__ and __LINE__ in the macro expansion to get you the uniqueness you seem to be going for... those metavariables get defined within the source file context, so be careful to make sure you get what you are looking for (e.g., perils of more than one macro on the same line).

How to generate a random variable or class name and use it later?

Since no one else wants to post the answer from the comments. (Examples from here)

The issues is that this violates the ODR:

// a.cpp
struct S {
int a;
};

// b.cpp
class S {
public:
int a;
};

One solution is put the definitions into an anonymous namespace in each file, preventing the linker from trying to re-conciliate the name with another translation unit.

// a.cpp
namespace {
struct S {
int a;
};
}

// b.cpp
namespace {
class S {
public:
int a;
};
}

Preprocessor macros: any way to get a unique variable name and reuse it?

You can use __LINE__ instead of the (non-standard) __COUNTER__. __LINE__ is the current line number in the source file of the original text (not the macro replacement text). So it doesn't change during the expansion of a macro, and it will be different for each macro expansion provided:

  • You never expand the macro twice in the same source code line
  • You don't try this trick from two different source files.

How can I construct a locally unique identifier name?

For a unique identifier, many implementations offer the __COUNTER__ preprocessor macro, that expands to an ever increasing number with every use.

#define CAT(a,b) CAT2(a,b) // force expand
#define CAT2(a,b) a##b // actually concatenate
#define UNIQUE_ID() CAT(_uid_,__COUNTER__)

auto UNIQUE_ID() = call(1); // may be _uid_0
auto UNIQUE_ID() = call(2); // may be _uid_1

Unique name for loop variable in macro

Several compilers support the __COUNTER__ macro variable that could be used to help avoid variable shadowing (you will still need to add a sufficiently unique prefix).

An example is given at: http://rentzsch.tumblr.com/post/12960046342/nearly-hygienic-c-macros-via-counter

The idea is to create a macro that take in the variable name suffix to use, then wrap that with a second macro that passes in __COUNTER__ to generate a unique suffix.

Generate a random number using the C Preprocessor

I take your question that you want to have a way of creating unique identifier tokens through the preprocessor.

gcc has an extension that is called __COUNTER__ and does what you expect from its name. You can combine this with macro concatenation ## to obtain unique identifiers.

If you have a C99 compiler you can use P99. It has macros called P99_LINEID and P99_FILEID. They can be used as

#include "p99_id.h"

P99_LINEID(some, other, tokens, to, make, it, unique, on, the, line)

and similarily for P99_FILEID.

The first mangles a name from your tokens and the line number and a hash that depends on the number of times the file "p99_id.h" had been included. The second macro just uses that hash and not the line number such that a name is reproducible at several places inside the same compilation unit.

These two macros also have counterparts P99_LINENO and P99_FILENO that just produce large numbers instead of identifier tokens.

Creating macro using __LINE__ for different variable names

You need to use combination of 2 macros:

#define COMBINE1(X,Y) X##Y  // helper macro
#define COMBINE(X,Y) COMBINE1(X,Y)

And then use it as,

COMBINE(x,__LINE__);


Related Topics



Leave a reply



Submit