views:

274

answers:

4

Hi,

I am trying to create a macro that takes a scope as a parameter.
I know, it is probably not a good thing etc etc.
I was trying this and got the problem that preprocessor looks for commas and parentheses... the problem is with enum.

How would I declare a enum inside a scope that is a parameter of a macro?

when the compiler see the comma between enum itens, it takes it as a separator.

If you are curious to know why I entered into this, is because I need to register my namespaces and classes, for namespaces I need to know when they are closed, so I was thinking to create a macro that initially calls a static function that register the namespace, encapsulate its contents and finally call a static function that removes the namespace from the registry.
With a macro it would be easier for the coder to do this and make sure he doesn't forget to remove the namespace in the end of the bracket.

Thanks,
Joe

EDIT:

I want a macro that accepts a scope as parameters:

#define MYMACRO(unkownscope) unknownscope

class MYMACRO({
   // please, don't take this code seriously, it is just an example so you can understand my question
});

now, if I try:

#define MYMACRO(unkownscope) unknownscope

class MYMACRO({
  enum {
    anything = 1,
    everything = 2
  };
});

it won't compile because of the comma inside the enum, because the compiler thinks it is a separator of the macro. It doesn't happen with commas inside parentheses, example:

 int a(){
    int x = anyfunction(1, 2);
 }

would compile normally because the comma is inside a double parentheses.

Sorry for not being able to explain earlier... my english is not that good and the words just keep skipping me =[

Ty for the answers!
Joe

+1  A: 

It sounds like you are pushing the preprocessor beyond where it's willing to go. While it's not as elegant, how about breaking your macro in two (one pre- and one post-) and rather then passing a "scope" as parameter, you surround your scope with you pre- and post- macros.

So, if your macro looks something like:

SOMACRO({ ... });

You would instead do something like:

PRESOMACRO();
{ ... };
POSTSOMACRO();
R Samuel Klatchko
yes, I said that on my post. I was just verifying if there was another way, for learning purposes. The difference between using two macros, one at the begin of the scope and one at the end, is that the coder can forget about one of them, specially the ending one. What I will do is create the complete macro that calls the beginner and finisher macros and if the coder needs enums, then he won't use this macro but the complete way, or should I push it to use just the two macros, regardless the flaw of forgeting the ending one?
Jonathan
A: 
#define SCOPED_STUFF(pre,post) pre; STUFF; post;

#define STUFF enum {a,b,c}
SCOPED_STUFF(a,b)
#undef STUFF

#define STUFF enum {q,r}
SCOPED_STUFF(c,d)
#undef STUFF
wrang-wrang
A: 

You are attempting to replicate RAII with a macro.

#define SCOPE(ns) NamespaceRegistrar _ns_rar(ns);
struct NamespaceRegistrar {
    std::string _ns;
    NamespaceRegistrar(const std::string& ns) : _ns(ns) { AcquireResource(_ns); }
    ~NamespaceRegistrar() { ReleaseResource(_ns); }
};


{
     SCOPE("Foo")
     // stuff
}

I have no idea what you are talking about with regard to enums.

jmucchiello
A: 

You already noticed what the problem is, an article on boostpro.com sums the problem up.
There are work-arounds, but i'd go for utilizing Boost.Preprocessor.

Without knowing exactly what you're trying to achieve syntactically, something like this might be what you are looking for (edited to PP_SEQ):

#define MAKE_ENUM(Name, Seq) enum Name { BOOST_PP_SEQ_ENUM(Seq) }
MAKE_ENUM(foo, (a)(b)(c));
Georg Fritzsche