Re: Circlemud design issues

From: James Turner (turnerjh@XTN.NET)
Date: 04/20/98


George <greerga@CIRCLEMUD.ORG> writes:

> But without going to C++, 'getName(ch) = NULL;' would not work as it does
> now.  You'd either have to keep the macro, make a setName(), or use the
> full structure.

That kind of assignment _shouldn't_ work.  Lvalues are a nice effect
of macros, but in general, using as such isn't the safest.

> You have to be smarter than the code.  When things are simple, you make it
> a macro. If you outgrow the macro, then you either add a more general macro
> or convert it to a function depending on your need.

This is the kind of argument people put against strong type checking.
There are times when you do have to be smarter than the code, but when
it can do work for you, when the language is designed for certain
kinds of work, we should let it do it.

> >>         As for three if/and/or code, wouldn't you be duplicating that in a
> >>  function anywway. Whats the big deal if its a function or a macro? Just
> >>  make sure to include your backslash, and its the same thing.  And if a
> >>  macro is already set up, wouldn't it be harder (20 seconds more) to turn
> >>  it into a function than just adding another && IS_A_DEAF_MUTE(ch) to the
> >>  end?  C'mon.
> >
> >Functions and macros are NOT the same thing by including backslashes.
>
> He wasn't saying they were, just that you would duplicate the check the
> macro does inside the function anyway.  So in the effort to avoid multiple
> && and || in a macro, you'd end up with them anyway in the function.

Macros and functions are fundamentally different, though he implies
(and more or less says) he feels they aren't.  They look the same, but
they're not.  Just like the usage of the if, while, and for keywords
can look like functions.  Using the similar appearance as
justification for using macros where functions are more appropriate
isn't valid.

And you're right, I think we are going to have to agree to disagree on
this.

> >Macros do not have typechecking, for one.
>
> Which is why you have to be smarter than the code.  As an example, you
> should know not to do GET_MOB_VNUM() on a room.

GET_MOB_VNUM() is certainly clear as to what it does and what
parameters it takes.  GET_NAME() isn't -- what does it get the name
of?  Can it be used on objects, rooms?  Also, other macros, such as
GET_ALIASES(), work only on players and will segfault on mobs -- yet
no checks are made.  Yes, it would be best to be careful when you use
these -- but no one is perfect.  Runtime warnings would be much easier
to diagnose than bizarre segfaults.  Plus, it would give an extra
level of assurance.  I'd rather the code recover when possible than
segfault when passed a parameter that is invalid.

> >Another issue is that some macros cannot be placed in some situations.
> >For instance, if you want to have multiple expressions in a macro, you
> >have to surround it with a do {} while(0) loop.
>
> But you just placed the macro in that situation.

And it's a dirty hack to do it.  It's using trickery to get around an
inherent limitation of the language.  My biggest objection is the
abuse of the language _when it isn't necessary_.  Sometimes, on rare
occasions, it is.  But this just isnt' one of them.

> What do you have in mind where you cannot use a macro?  If you mean
> variable arguments, that doesn't count since you can just #define the name
> of the function without the ().

Actually gcc supports varargs in macros.  It's an extension though.

Generally speaking, the more involved a piece of code is, the harder
it is to turn into a macro.  More than that, the more involved it is,
the less correct it is to use a macro.  CAN_SEE is a great example.
Further, if you later chose to add checks to the code, or increase
functionality, you wouldn't have any trouble doing so.

assert() is a great way to catch errors in debug builds and not lose
efficiency in production builds.

> >Macros have their uses;  but they shouldn't be used as blindly and
> >frequently as the current code does.
>
> This is starting to sound like a holy war.

Perhaps, but that is not the intention.

> >Your view of what a macro is is somewhat incorrect.  They are not just
> >like functions -- they are fundamentally different.  There is a large
>
> They can be just like functions in most respects.  They don't have to be,
> but they can be.

Yes, they can be... but if you use them just like functions, they
should _be_ functions in the first place.  Speed isn't really an issue
-- even without inlining, the overhead will be negligible.  Yes, it
would take time to convert the macros; but we would gain flexibility,
reliability, and robustness.

> >amount of documentation of this in the literature and on the net.  I
> >would suggest checking into some of this if you are still not clear on
> >the distinctions.  You have an intuitive feel for macros; however,
> >that is not sufficient.
>
> I'd like to see you do token pasting with functions.

By that I assume you mean something like

#define cat(a,b) (a ## b)

As I said above, there _are_ things only achievable with macros.
However, the current code uses them as shortcuts -- dangerous
shortcuts -- not as ways to accomplish what can't otherwise be done.

--
James Turner               turnerjh@xtn.net
                           http://www.vuse.vanderbilt.edu/~turnerj1/


     +------------------------------------------------------------+
     | Ensure that you have read the CircleMUD Mailing List FAQ:  |
     | http://democracy.queensu.ca/~fletcher/Circle/list-faq.html |
     +------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/15/00 PST