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
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();
#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
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.
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));
Related
Folks,
Problem Statement - Does C++ allow a (static) const be limited to a class scope, so I can get rid of #defines that pollute entire namespace?
My observation is NO (in the following DIFFERENT examples), and I'd like to find out why and what's the best alternative. VS generates error C2589: 'const' : illegal token on right side of '::'
EXAMPLE1
// a.h
class A
{
…
..
static const uint_32 myConst = 1234;
};
//b.cpp
include “a.h”
…
B()
{
uint32_t arr[A::myConst]; // C2589! const : illegal token on right side of '::'
}
EXAMPLE 2
// a.h
class A
{
…
..
enum blah
{
...
myConst = 1234,
..
};
};
//b.cpp
include “a.h”
...
B()
{
uint32_t arr[A::myConst]; // C2589! const : illegal token on right side of '::'
}
When you take your macro:
#define CONST 1234
and substitute it for where you use it:
static const int CONST = 1234;
The end result is nonsense:
static const int 1234 = 1234;
In another instance:
Int a1[a::CONST];
This also becomes nonsense:
Int a1[a::1234];
This all begs the question, what are you trying to do?
It looks like you're trying to create a member variable with the same name as your macro, CONST, here:
class A
{
static const int CONST = 1234;
};
However since when this code is compiled the macro has already been defined, the preprocessor changes this by substituting the macro before the compiler itself can get a crack at it. By the time the code is compiled, it looks like this:
class A
{
static const int 1234 = 1234;
};
Best is to just do away with the macro entirely, and then retrofit your code to use proper constants like you're trying to do here. Don't mix and match. At the very least, don't use the same name for the member as you do for the macro.
First of all your class is called A, as in capital A, not a. The class name is used to qualify the constant you are trying to use. So, change your code to use A::CONST. By the way, this is C++ not C# or Java, so there is no such thing as an Int, unless for some bizarre reason you decided to invent your own integer type.
As an aside, using all caps to name constants can collide with macros and is a good way to get into trouble, especially since pre-processing happens first and macros are substituted for all cases of the constants. This can often lead to invalid C++ code with syntax errors that are difficult to understand. That's why you should never use all caps to name constants, since this is a convention most commonly used for macros.
If I may make a guess, it looks like you're trying to use :: the same way you use . in Python.
It looks like you really don't understand what the scope resolution operator does, or how it works.
:: has a very specific, and quite limited usage. Until you understand it better, we're going to have a really hard time helping you.
How can I create a typedef using a macro (#define)?
I am, for various reasons, trying to use a macro to do typedef'ing in C. Something along the lines of templates for C++.
As an example, I would expect the preprocessor to expand the #define and typedef a struct whose "content" member is of type char:
#define DEFINE_FOO_TYPE(content_type__, content_type_name__) \
typedef struct { \
content_type__ content; \
} content_type_name__
DEFINE_FOO_TYPE(char, foo_t);
foo_t foo_var;
foo_var.content = 'g';
Apparently that is not the case. Is it possible to do these sort of things in C at all, or is the only way a C++ template?
To preempt questions along the lines of "why don't you just use a C++ template?". The answer is that I'm trying to do it in C because it's fun.
Try this:
#define DEFINE_FOO_TYPE(content_type__, content_type_name__) \
typedef struct { \
content_type__ content; \
} content_type_name__
DEFINE_FOO_TYPE(char, foo_t);
int main() {
foo_t foo_var;
foo_var.content = 'g';
return 0;
}
I.e. use content_type_name__ instead of element_type_name__
Proof of compilation
I posted in a comment because I thought it was too trivial, but here it is:
Surely you are not just pasting that quoted code into gcc, are you? You can't just execute code outside any function. Put the last line inside a function.
simply put the last two lines of code into main()
or any function it will work for sure.
I was having trouble with the following macro, and I found out that the token-pasting operator (##) is eating the space between static and the return type:
#define MY_FUNCTION(aReturnType) static ##aReturnType MyFunction() { }
So the preprocessor was turning this:
MY_FUNCTION(bool)
into this:
staticbool MyFunction() { }
which caused weird compilation errors.
I came up with the idea of putting parentheses around the static keyword:
// This works but is kind of weird
#define MY_FUNCTION(aReturnType) (static) ##aReturnType MyFunction() { }
Are there any better solutions?
I think that your problem is that you don't want to use token pasting here. If you change the macro to
#define MY_FUNCTION(aReturnType) static aReturnType MyFunction() { }
Then if you write
MY_FUNCTION(bool)
it will expand out into
static bool MyFunction() { }
I am assuming that this is what you want to do, since I can't see what you're trying to paste the aReturnType argument to the macro onto.
Hope this helps!
As it should do? You told it to paste together static and bool. If you don't want that and you want static bool instead, then don't paste them together?
I have a lot of legacy code using macro of the form:
#define FXX(x) pField->GetValue(x)
The macro forces variable pField be in the scope:
.....
FIELD *pField = ....
.....
int i = FXX(3);
int j = FXX(5);
Is there way to replace the macro, without touching user code?
Since FXX(x) has a function invocation style, I thought about inline function or something similar.
UPD:
People just used to the macro, and I want to remain it as is.
How about using a find & replace function in your favorite editor...I think it would work fine in the example you gave in your question. Replace FXX with pField->GetValue and then remove the #define line
What is pField (besides a fine example of the abomination that is Systems Hungarian)? If, by chance, it's a global variable or a singleton or something that we only need one of, we could do a nifty trick like this:
int FFX(int x)
{
static FIELD *pField = ...; // remove this line if pField is global
return pField->GetValue(x);
}
Change the int types to whatever types you need it to operate on, or even a template if you need it to support multiple types.
Another alternative, suggested by #epatel, is to use your favorite text editor's find-and-replace and just change all the FFX(x) lines to pField->GetValue(x), thus eliminating the macro invokation in your code. If you want to keep a function invokation, you culd change FFX(x) to FFX(pField, x) and change the macro to take two arguments (or change it to a function that takes two arguments). But you might as well just take out the macro at that point.
A third alternative, is not to fix that which is not broken. The macro isn't particularly nice, but you may introduce greater problems by trying to remove it. Macros aren't the spawn of Satan (though this one has at least a few relatives in hell).
What you need is a function that relies on a variable being defined. The only way to do that is to declare that variable in the same scope as the function. But then your function would use that one instead of the one declared from where your function is called.
So I'm fairly confident it can't be done.
Well, if you can put this function definition where pField is already in scope:
int FXX(int x) { return pField->GetValue(x); }
Otherwise, there's no way to get pField into the the function without affecting existing code.
This may be a case where using the macro is the best alternative. Macros may be evil, but they are sometimes necessary. See http://www.parashift.com/c++-faq-lite/big-picture.html#faq-6.15
I would leave it as it is, but just for the sake of discussion, and depending on what parts of the code are 'untouchable' you could define a functor that takes a pField and initialize after the variable is created in the same scope:
class FFX_t {
FFX_t( FIELD * pField ) : field_(pField) {}
int operator()( int index ) {
return field_->GetValue( index );
}
private:
FIELD *field_;
};
// usage:
void f() {
FIELD * pField = //...
FFX_t FFX(pField); // added after pField construction
// ...
int a = FFX(5);
}
But I insist in that changing working code for the sake of it when it will not really add any value is useless.
Suppose I have a C++ macro CATCH to replace the catch statement and that macro receive as parameter a variable-declaration regular expression, like <type_name> [*] <var_name> or something like that. Is there a way to recognize those "fields" and use them in the macro definition?
For instance:
#define CATCH(var_declaration) <var_type> <var_name> = (<var_type>) exception_object;
Would work just like:
#define CATCH(var_type, var_name) var_type var_name = (var_type) exception_object;
As questioned, I'm using g++.
You can't do it with just macros, but you can be clever with some helper code.
template<typename ExceptionObjectType>
struct ExceptionObjectWrapper {
ExceptionObjectType& m_unwrapped;
ExceptionObjectWrapper(ExceptionObjectType& unwrapped)
: m_unwrapped(unwrapped) {}
template<typename CastType>
operator CastType() { return (CastType)m_wrapped; }
};
template<typename T>
ExceptionObjectWrapper<T> make_execption_obj_wrapper(T& eobj) {
return ExceptionObjectWrapper<T>(eobj);
}
#define CATCH(var_decl) var_decl = make_exception_obj_wrapper(exception_object);
With these definitions,
CATCH(Foo ex);
should work. I will admit to laziness in not testing this (in my defence, I don't have your exception object test with). If exception_object can only be one type, you can get rid of the ExceptionObjectType template parameter. Further more, if you can define the cast operators on the exception_object itself you can remove the wrappers altogether. I'm guessing exception_object is actually a void* or something though and your casting pointers.
What compiler are you using? I've never seen this done in the gcc preprocessor, but I can't say for sure that no preprocessor out there can implement this functionality.
What you could do however is run your script through something like sed to do your prepreprocessing so to speak before the preprocessor kicks in.
Hmmm... I'm just guessing, but why don't you try something like this : :)
#define CATCH(varType,varName) catch(varType& varName) { /* some code here */ }