-1

A way to create random (actually sequentially numbered) variable names is demonstrated in the question How to generate random variable names in C++ using macros?.

However, it is not explained how such a generated name can be accessed later. Imagine a class declaration with a constructor. You need the same random name for the class name and the c-tor. Always using the generator macro just generates a new identifer and the compilation fails. Here's an example:

#define CONCAT_(x,y) x##y
#define CONCAT(x, y) CONCAT_(x, y)

#define DESCRIBE_IMPL CONCAT(DescribeImpl, __COUNTER__)
class DESCRIBE_IMPL {
public:
  DESCRIBE_IMPL() {}
};

I tried storing the current counter value somehow (e.g. enum { COUNTER = __COUNTER__ }, but using this enum always leads to the name DescribeImplCOUNTER instead of the variant with the counter value.

The Real Problem

What I'm trying to solve with this approach is a case where I have multiple definitions of the same class in different cpp files (generated from macros) and the linker complains about multiple symbols (ODR violation). I cannot change this approach without significantly change the usage pattern.

12
  • This trick is only viable for things where the name is a throwaway. What are you really trying to solve? You seem to be asking about your perceived solution. Commented Apr 2, 2019 at 11:27
  • 3
    What is the real problem you try to solve with a solution like this? For "sequentially numbered" variables, one usually uses arrays or similar data-structures. Having a set of otherwise equal variables or classes clutters up the code, making it hard to read, understand and maintain. Using macros to "create" these symbols does't make it better. Commented Apr 2, 2019 at 11:28
  • Youy guys are right, this is part of a bigger problem and I tried to leave out as much irrelevant as possible. This approach is one attempt to solve the real problem. Let me add some information in my question. Commented Apr 2, 2019 at 11:31
  • 1
    The built-in non-standard macro __COUNTER__ is per translation unit, so if you use the macro in different translation units it will not help. I think you should delete this question, and try to come up with an minimal reproducible example for a new question where you ask about your real and underlying problem instead. Commented Apr 2, 2019 at 11:44
  • 4
    Have you tried putting your class in your cpp files in the anonymous namespace? Commented Apr 2, 2019 at 11:54

1 Answer 1

0

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;
};
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.