Archived

This topic is now archived and is closed to further replies.

#defining (?)

This topic is 5267 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I don''t really know what to call this so I''ll bring en example: suppose you have something like this (the example below is pure fiction): Global->Object->Properties->Type->Flags You have a lot of properties in class Global so you''re looking for a way to truncate the expression. What I''d like to do is to use a simple define, such as: #define Object-> Global->Object-> The above code won''t compile, though because the compiler expands it to this: #define "Object" "-> Global->Objects->" I added the quotes for clarity. Defining the Object without the trailing arrow isn''t good either because it can lead to problems with the word Object in the middle or beginning of an irrelevant variable name. I do recognize that what I''m trying to do is very error prone (if a variable name ends with the word Object and points to a nested item, the replacement will produce an error), but I''m really beginning to have a problem with so many (4 or more) levels of nested references. Any ideas?

Share this post


Link to post
Share on other sites
Instead of a #define, use an alias pointer:


// this is bad

Global->Object->Properties->Type->Flags = ...;

// set up an alias pointer:

ObjectType *alias = Global->Object;
// and use it to access stuff:

alias->Properties->Type->Flags;


It has the exact effect you''re looking for, is much safer than #defines and as an added bonus, this method will provide you with an extremely small speed boost because you''re not dereferencing multiple things all the time.

-Auron

Share this post


Link to post
Share on other sites
JohnBSmall and AP: Yeah, I could do that, but that might actually be even more confusing. I generally have up to 4 or five such kind of "deep references" in one function so instead of a speed boost I might end up with a speed loss (memory allotment and cleanup for a new variable each time the function is called).

Making these aliases gloabl would most likely help, but that would in my case produce at least 20 new globals...

ToohrVyk: consider this:


#define Object Global->Object

main()
{
//bla-bla
MyObjectManager->Flush();
}



Share this post


Link to post
Share on other sites
quote:
I generally have up to 4 or five such kind of "deep references" in one function so instead of a speed boost I might end up with a speed loss (memory allotment and cleanup for a new variable each time the function is called).

Uh, so you're saying stack allocation of these variables is going to slow you down? Get a grip man.

Write the most clear thing and profile later! No need for #define's in this case. Something tells me this portion of the code isn't speed sensitive, too. Why else would you be assigning so many things?

[edited by - antareus on August 16, 2003 4:54:20 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Crispy
ToohrVyk: consider this:


#define Object Global->Object

main()
{
//bla-bla
MyObjectManager->Flush();
}



What about it? I see no problems there.

Share this post


Link to post
Share on other sites
It''s no wonder the preprocessor is turning

#define Object-> Global->Object->

into the string "Object" "-> Global->Objects->"

-> is not part of a valid name.


Try something like this

#define MYMACRO(g) g->Object->Member

and then use it like so

MYMACRO(Global);

Another variation

#define MYMACRO(o, m) Global->o->m

and use it like so

MYMACRO(Object, Member);

and another

#define MYMACRO(g,o,m) g->o->m

and like so

MYMACRO(Global, Object, Member);

Remember, the preprocessor performs a text substitution on the code and the resulting substituted text is what gets sent to the compiler.

so MYMACRO(Global, Object, Member);
ends up looking like

Global->Object->Member;

before it gets compiled.

If for some reason there is no Object member of Global, or no Member memer of Object, you''ll get a compile time error that might not easily be tracked down.

Consult the docs for your compiler regarding what kinds of command line switches are available. One of them should direct the compiler to dump the preprocessed code out to file. That code can be examined to determine whether or not a macro has substituted text as intended or not.

Share this post


Link to post
Share on other sites
Look Crispy, don''t use "#define" for this. It has already caused problems for you and it will continue to cause problems.

The smart thing to do is to follow JohnBSmall''s or Auron''s suggestion. It will not slow your code down and it might even speed it up. It will be less confusing than a bunch of "#defines".

Share this post


Link to post
Share on other sites
Yeah, I guess macros don''t really justify themselves here. Although I sort of like LessBread''s solution even if it doesn''t really dramatically cut down code size. If I''m not mistaken VB has the keyword
with 
that I sometimes really miss. Than again, it''s another way to further encrypt your code.

@Enselic: what''s the largest project you''ve ever worked on? Once you get to 100+ classes, believe me, you''ll want to wrap, if only to encapsulate, and then you''ll end up with monsters like these.

@Brother Bob: the expression "MyObjectManager->Flush();" with the macro substitution "#define Object Global->Object" expands to "MyGlobal->ObjectManager->Flush();".

Share this post


Link to post
Share on other sites
quote:
Original post by Crispy
JohnBSmall and AP: Yeah, I could do that, but that might actually be even more confusing. I generally have up to 4 or five such kind of "deep references" in one function so instead of a speed boost I might end up with a speed loss (memory allotment and cleanup for a new variable each time the function is called).

No! It will speed it up, instead, because everytime you write "->" the processor has to follow the pointer (indirection), and this is """"slow"""". If you have a pointer only to your top-level member variable, the indirections are only evaluated once.
quote:
Making these aliases gloabl would most likely help, but that would in my case produce at least 20 new globals...

The idea is not to have, for a->b->c->d->e, a pointer/reference to b, c, d, and e! The idea is to simply have one for e (or d, depending on what is convenient for you).

Don''t use #define. It''s evil.

Cédric

Share this post


Link to post
Share on other sites
quote:
Original post by Crispy
@Brother Bob: the expression "MyObjectManager->Flush();" with the macro substitution "#define Object Global->Object" expands to "MyGlobal->ObjectManager->Flush();".

#defines are not text substitutions, they are token substitutions. And since MyObjectManager != Object, there will be no substitution there.

Share this post


Link to post
Share on other sites