how to make a macro stringify and paste a -D defined arg

G

gry

[g++ 4.4.0, linux, large SW project so I can't change compilers or the
api I'm talking to]
I have a macro:
#define RegisterFactory(clazz) \
clazz clazz##_instance; \
extern "C" Foo::HHFactory *get##clazz() { return
&clazz##_instance; } \
Foo::HHRegistrar clazz##_registrar(#clazz)
which works fine for literal arguments. But when I give it an
argument that was defined on the compile line:

g++ -DFACTORYNAME=MyFactory

it fails. I understand why... the arg is used in paste and stringify
contexts -- but is there some reasonable way to fix this?
I want
RegisterFactory(FACTORYNAME) to expand to:
MyFactory MyFactory_instance;
extern "C" Foo::HHFactory *getMyFactory() { return
&MyFactory_instance; } \
Foo::HHRegistrar MyFactory_registrar("MyFactory")

The original macro is used in many places so I need something that
cleanly replaces it. I tried #define FACTORYNAME MyFactory, but no
difference(not that I really expected one).
 
K

Kalle Olavi Niemitalo

gry said:
#define RegisterFactory(clazz) \
clazz clazz##_instance; \
extern "C" Foo::HHFactory *get##clazz() { return &clazz##_instance; } \
Foo::HHRegistrar clazz##_registrar(#clazz)
which works fine for literal arguments. But when I give it an
argument that was defined on the compile line:

g++ -DFACTORYNAME=MyFactory

it fails.

Define a new macro that takes FACTORYNAME as an argument and
forwards it to your original macro (renamed below):

#define RegisterFactoryNoExpand(clazz) \
clazz clazz##_instance; \
extern "C" Foo::HHFactory *get##clazz() { return &clazz##_instance; } \
Foo::HHRegistrar clazz##_registrar(#clazz)
#define RegisterFactory(clazz) RegisterFactoryNoExpand(clazz)

#define FACTORYNAME MyFactory
RegisterFactory(FACTORYNAME);

Then, the preprocessor will expand FACTORYNAME.
http://c-faq.com/ansi/stringize.html
 
G

gry

Define a new macro that takes FACTORYNAME as an argument and
forwards it to your original macro (renamed below):

#define RegisterFactoryNoExpand(clazz) \
    clazz clazz##_instance; \
    extern "C" Foo::HHFactory *get##clazz() { return &clazz##_instance; } \
    Foo::HHRegistrar clazz##_registrar(#clazz)
#define RegisterFactory(clazz) RegisterFactoryNoExpand(clazz)

#define FACTORYNAME MyFactory
RegisterFactory(FACTORYNAME);

Then, the preprocessor will expand FACTORYNAME.http://c-faq.com/ansi/stringize.html

That works beautifully. Thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top