i understand that the macro is a code that is changed before compile it.
so i did these macro with these code:

#define (events2((y),(x))) (class events3 : public ( y ) { events3(); ~events3(); }(x) ; )
//#define (events2((y),(x))) (class events3 : public ( y ) { events3(); }(x) ; )
//#define (events2((y),(x))) (class events3 : public ( y ) { ~events3(); }(x) ; )
//#define (events2((y),(x))) (class events3 : public ( y ) { }(x) ; )

class b
{
    public:
    virtual void tests(){};
    b()
    {
        tests();
    }
};


events2( b) a;

void a::tests()
{
    write("oi");
}

and i get these errors:
"C:\Users\Joaquim\Documents\CodeBlocks\My Class\main.cpp|7|error: macro names must be identifiers|
C:\Users\Joaquim\Documents\CodeBlocks\My Class\main.cpp|23|error: expected constructor, destructor, or type conversion before 'a'|
C:\Users\Joaquim\Documents\CodeBlocks\My Class\main.cpp|25|error: 'a' has not been declared|
||=== Build finished: 3 errors, 0 warnings (0 minutes, 0 seconds) ===|"

what i'm doing wrong with these macro?

Recommended Answers

All 27 Replies

From your output: error: 'a' has not been declared

You should provide a as an argument to the macro. Like events2(b,a);

Also, it is often helpful to try and read the error messages and follow them in your code (I think Visual Studio actually allows you to double-click an error to go to the exact line). It is a helpful way to understand why you are getting errors and helps guide you to the correct solution.

i'm using code::blocks becuase of my big project ;)
sorry about that declaration mistake.
but let see the 1st error:
"C:\Users\Joaquim\Documents\CodeBlocks\My Class\main.cpp|7|error: macro names must be identifiers|"
what i miss up with my macro?

What are you trying to do? Tell us what you want the macro to transform this events2( b) a; into.

I don't think that MACROs can be wrapped in parentheses. The rules that the pre-processor works by are far simpler and crude than the rules by which the compiler works. The pre-processor is just a simple parser, a find-and-replace type of parser. So, the MACRO definition should be something like this:

#define events2(y,x) ..

Then, by convention, MACROs should always be written in UPPER-CASE LETTERS. This is a universal convention in C, C++, and any other language featuring a similar pre-processor feature. Do not break that convention. If you do, you will only attract the ire of 99% of the programmers who ever set their eyes on your code. I know that, personally, if I see code that breaks that convention, I will dismiss it, mock it, and shun it with extreme prejudice. In other words, use this instead:

#define EVENTS2(Y,X) ..

Then, I assume you have read somewhere that MACROs are dangerous because they can take almost anything as a "parameter" that is simply substituted into the MACRO's expression (in a "find-and-replace" style). And also, that MACROs are dangerous because they could be put in any weird places. And that one of the guidelines related to these two problems is to be very generous with parentheses, to make sure that whatever is provided as a parameter to the MACRO is going to be inserted between parentheses and that the MACRO expression as a whole should be wrapped in a set of parentheses (because of the second problem mentioned). Now, in reality, this is really a guideline which applies to a "function" MACRO, that is, something like a MAX MACRO:

// this is dangerous:
#define MAX(X,Y) X > Y ? X : Y

// this is better:
#define MAX(X,Y) ( ( X ) > ( Y ) ? ( X ) : ( Y ) )

This is because those kinds of MACROs are expected to be used within expressions, such as
a = b + c * MAX(d,e);, where the lack of parentheses to isolate the evaluation of the MACRO or its parameters could lead to operator precedence issues and stuff like that which would yield surprising and wrong results.

In your case, that guideline does not apply, because your MACRO is a kind of "automated declaration" MACRO, meaning that it is used in a declaration context, which does not really have much of those issues. And generally, it is a bit unusual to have declarations littered with parentheses, and I'm not even sure the compiler will always accept them (for example, I'm not sure that wrapping an entire class declaration in parentheses is OK, or that wrapping the base-class name in parentheses is OK either).

Finally, it seems to me that what you really want here is a multi-line MACRO, which you can acheve using the slash character at the end of a line (warning, it must be the absolute last character in the line, spaces after it are not even acceptible).

I think this is closer to what you might be looking to achieve:

#define EVENTS2(Y,X) \
  class events3 : public Y { \
    events3(); \
    ~events3(); \
   } X;

The reason why there is no need to wrap Y or X in parentheses is because the only acceptable thing you can pass for them is a single identifier: Y must be a class name; and, X must be a name for the variable you are declaring.

And, lastly, to use that MACRO correctly, you would need this:

EVENTS2(b,a)

Which is ugly and unclear, as MACROs always are. Please consider every possible alternative before using a MACRO. MACROs are an absolute last resort.

thanks for the tutorial about macros my friend.
i belive the macro have 1 problem:

#define write(x)  cout<< x

    #define EVENTS2(Y,X) \
    class events3 : public Y { public: \
    events3(); \
    ~events3(); \
    } X;

class b
{
    public:
    virtual void tests(){};
    b()
    {
        tests();
    }
};


EVENTS2(b,a);

void a::tests()
{
    cout << "oi";
}

because of these error:
"C:\Users\Joaquim\Documents\CodeBlocks\My Class\main.cpp|29|error: 'a' is not a class, namespace, or enumeration|"

i fix it:

    #define EVENTS2(Y,X) \
    class X : public Y { public: \
    X(); \
    ~X(); \
    } X;

class b
{
    public:
    virtual void tests(){};
    b()
    {
        tests();
    }
};


EVENTS2(b,a);

a::a()
{
    cout << "oi";
}

a::~a()
{
    cout << "bye";
}

but see 1 problem.
the class 'a' needs declare the base functions(the virtual functions). how can i do it inside of macro?

Why on earth do you want to do this?

I don't get it. All your MACRO achieves is making everything cumbersome and unclear.

As far as adding some, virtual functions, I don't see why you can't:

#define EVENTS2(Y,X) \
    class X : public Y { public: \
    X(); \
    ~X(); \
    virtual void tests(); \
    }

class b
{
    public:
    virtual void tests(){};
    b()
    {
        tests();
    }
};


EVENTS2(b,a);

a::a()
{
    cout << "oi";
}

a::~a()
{
    cout << "bye";
}

a::tests()
{
    cout << "test";
}

It's that simple.

i will explain better;)
but let me ask you 1 thing: i must declare all virtual functions or theres another command for do it?
(if there isn't i must give up on these code :()
imagine that Y have 10(or more) virtual functions, i must declare the 10. or theres another way for have them?

Well, you only need to declare the virtual function you wish to re-implement in the derived class. If you don't need to re-implement it, then you don't need to re-declare it.

i don't want bored you.(imagine that we don't tests() have inside of macro)
why i can see in list when i do 'void a::'?
what i need is use them without declare them inside of macro.
but seems, like you said, that i can't :(
ok..thanks for all.. thanks

i re-read your tutorial, but i continue falling :(
see these other macro:

#define EVENTS(a)(...)  events<...> a{[](...) { ; }};

tell me where i'm failling please:(

EVENTS(a)(...) is not a valid way to declare a MACRO, it has to be EVENTS(a,...). In other words, a MACRO declaration cannot be anything else, just a name, a set of parenthesis with a list of names in it. That's it. MACROs are very simple and cannot accommodate anything fancy.

i continue with very errors messages. see the original example:

events<int,int> moved{[](int a, int b) { ; }};

i need convert it to a macro(for just avoid the templates arguments):

EVENTS(moved,int a, int b);

i'm using what you correct me(thanks for that).
if you tell me these is impossible... thanks anyway and thanks for all

Would you mind explaining why you need to avoid template arguments in this? I would think templates would be the preferred approach for this, in C++.

This is going too deep down a road I cannot follow. There is only so much I can do in terms of giving good advice on how to implement a terrible solution. When going down that road, at some point, there's a rupture, and I have to just say: Don't do that, don't try.

You seem obsessed with this, and I don't see any reason why you are doing this. Why would you want to use a MACRO (with all the problems that come with it) just to avoid a minor inconvenience (explicit template arguments)? The trade-off is terrible.

This whole thing just seems like a classic case of an XY problem.

i'm doing these for be more easy to convert my language to C++. but like you said for don't go in these way, i stop it ;)
thanks for all to both

mike_2000_17 i see what you mean by that link. sorry about that. i just was trying be more simple, but sometimes we can't

Yeah, the whole "trying to make things simple" road can be a tricky one. It is easy to get obsessed with a particular path and lose sight of the original objective, i.e., making things simpler and easier. It is noble to try to make the user-side code simpler (e.g., avoiding explicit template arguments), but if that means requiring the user to learn a whole new MACRO-based pseudo-language with many pitfalls, it isn't really achieving the real objective, is it? The real objective is to make things as simple as possible, not to eliminate the one thing you perceive as "not simple enough", especially not if it involves introducing some other weird, complicated and tricky scheme.

do you know why i'm build a new language?(ok using the c++ compiler, because i just convert it to C++)
- be simple to use like VB6(VB2010 in very things seems complex);
- powerfull like C\C++;
- anotherthing: 'limit is your imagination'. for exemple:

      - you don't use Console for games(normaly), but why not let the programmer do it, if want it ;)
      - VB2010 have nice functions in Console class... hey can i change the window size?? or change the window position?(i continue with Console);
      - VB2010 it's great, but why i can't change the alpha\transparent values with controls?(yes they have it, but aren't real... because they just copy the parent background image;
      (and more)

i understand that i'm speak out off topic, but you get the point ;)
anotherthing: realy... thanks for all... thanks

Hmmm... it is very much sounding like you want to develop an Domain-Specific Embedded Language (DSEL). C++ is definitely the best, if not the only, programming language that truly allows you to do that. However, making a DSEL is very complicated and requires a very high level of competence in C++ and deep knowledge of the language mechanism.

The main tool that you use for that is template meta-programming, which is a kind of advanced use of templates to perform complex compile-time type-manufacturing. In short, this is really advanced stuff, it takes years to really master that art.

And relying on MACROs to try to do this is not realistic. MACROs are far too limited, and error-prone.

more dificulty is how detect all types of errors;)
i have 1 function in VB2010(yes i use the VB2010 for do the conversion and the IDE) for separe all keywords\functions names\special characters\strings(not yet for chars and comments). these function make 50% of my work;)
i will change all what i did, because i must change my language sintax. will be great(think in VB6).

I just want to point out one thing: Many programmers hate VB with a passion. So, aiming for something like "great (think of VB6)" is not exactly something most people would find attractive. Most people associate VB with qualificatives like "aweful", "verbose", "archaic", "obsolete", "inflexible", ... in other words, bad.

If you want to make a DSEL that is oriented towards expressing the creation of GUIs (what VB is for), then that's a noble pursuit, but I wouldn't really take VB as an example.

If you just want to be able to write VB-looking code in C++, then I guess that's a good exercise (for DSEL), but not exactly a very appealing thought to most, I would say.

more dificulty is how detect all types of errors;)

You probably can't even imagine how spot-on that is. The best and the worst part of making a DSEL is enforcing the DSEL's rules (i.e., detect errors). It's the best part because it's something you can do, and if you do it well, the results are amazing. It's the worse part because it's really really hard to produce, and requires huge test-harnesses.

have you seen the image that i send you?
you can see that it's like VB6 code. and it's good have 1 powerfull language with easy syntax and easy language ;)
and good for my pratice too. i learn Assembly and Turbo Pascal(i forget both)... i discovered that i love programming, so i discovered the VB6.. and then i see it's limits. my language you will simple too, but with some class's for allmost we use(multithread, timer(for now is 10ms of precision), strings, Console, instead Graphics i will use the Sprite(combine images with effects and shapes), controls(i must learn about API windows), and more).. will give me work. but what will give me work will be the properties and events, because they aren't directly in language ;)

At this stage, you might want to take this to a new thread, as it is going well out of the original topic; for that matter, private mail may be a better choice in general for this discussion.

Cambalinho: at this stage, I think you are no longer looking at something that could reasonably done as a DSEL, but are talking of a full language. You may want to look into how languages are designed and implemented in greater detail before proceeding. You'll also want to consider what 'features' you need in your core language, and which ones would be better implemented in the language libraries.

Finally, please look at some other existing languages to get a wider view of what already exists - there are literally thousands of languages already designed, and it is likely that something already out there will prove inspiring to you. I think that both Python and Dark Basic might be of interest to you, even if neither quite fit what you are looking for. Take a look at some of the more esoteric languages as well, such Scheme, Haskell, and Erlang, to broaden your view of what programming can be; you'll find that rewarding, I think, even if you never use any of them. You may even find, as I did, that one of them has a perverse appeal to you (hence my own language design work being mostly in the Lisp family of late).

thanks for all, but i just was explain nothing. if i realy need it, i will do a new thread. thanks for the links. thanks for all to all

can anyone tell me all the macro consts?

Does that mean you are trying to write your own compiler? If yes, then check out Yacc (Yet Another Compiler Compiler) or Bison which translates Yacc code into C code.

can anyone tell me all the macro consts?

Huh? See this article. macros are evil -- sould not be used.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.