C++ macros

Code junkies hangout here

Moderators: ChrisThornett, LXF moderators

C++ macros

Postby tedius » Mon Jun 27, 2005 10:34 am

I'm trying to write a macro that will call a function to copy some values.
The extract below is only a small part of my program but I hope it will give you the idea of what I'm trying to do.

Code: Select all
#define COPY_ATT(dest, source, num) \
  copyAtt((dest)->att_ ## num, \
               source,
               num);

std::string[3] list;

class object
{
  std::string att_1;
  std::string att_2;
  std::string att_3;
};

copyAtt(std::string att,
            std::string[] list,
            int index)
{
   att = list[num-1];
}

int main()
{
  object *pObj new object;

  for (i = 1; i <= 3; i++)
    COPY_ATT(obj, list, i);
}


What is happening is that the macro is evaluating to (on the first loop)
Code: Select all
copyAtt(pObj->att_i,
            list,
            1);


Where I was hopping for
Code: Select all
copyAtt(pObj->att_1,
            list,
            1);


Is it at all posible to do what I want, and if so can some one tell me where I'm going wong.

Thanks
User avatar
tedius
 
Posts: 84
Joined: Fri Apr 08, 2005 3:20 pm
Location: Cambridge, England

RE: C++ macros

Postby vorian » Wed Jun 29, 2005 8:30 pm

Macros are evaluated by the preprocessor not the core compiler. You should treat it like string substitution.
After the preprocessing stage your code looks like:
for (i = 1; i <= 3; i++)
copyAtt((dest)->att_i, \
list,
i);
now the core compiler gets to work and seeks to find a att_i attribute (there is none ).
vorian
 
Posts: 1
Joined: Wed Jun 29, 2005 8:20 pm

RE: C++ macros

Postby jjmac » Wed Jun 29, 2005 10:16 pm

Thats a really good problem :)

But, as suggested above ... the preprocessor can only reall do a compile-time substitution. And it will require a 'constant' to use in the substitution.

Where as, your looking for a run-time evaluation. I don't think the preprocessor can do that.

You would need to provide some trick to allow for a 'constant' to be passes, like the below.

Code: Select all

    for (int i = 1; i <= 3; i++){

    switch (i){

        case 1:
          COPY_ATT(ob->att_1, i, i);
          break;
        case 2:
          COPY_ATT(ob->att_2, i, i);
          break;
    }
  }



That could get somewhat messy if you had a lot of strings to copy.

As a container ... why not use a 'vector' instead ?. Sounds like it would be perfect for what you see, to be doing there.

About all i know about macro substitions though, comes from here ...

http://gcc.gnu.org/onlinedocs/cpp/Macros.html

So i could well be missing something there :)


jm
jjmac
LXF regular
 
Posts: 1996
Joined: Fri Apr 08, 2005 1:32 am
Location: Sydney, Australia

Postby tedius » Thu Jun 30, 2005 1:18 pm

Thanks for the help guys.

I had sort of come to the conclusion that what I was trying was not going to work :(

The solution that I am using is just to remove it from the loop and do one line for each copy. It works, but with 34 attributes to copy I was hoping for something more cleaver. :)

jjmac.

The reason I didn't use a vector is that the struct that I'm coping to is already define, and I don't have control over it :(
User avatar
tedius
 
Posts: 84
Joined: Fri Apr 08, 2005 3:20 pm
Location: Cambridge, England

Postby jjmac » Fri Jul 01, 2005 10:55 am

>>
The reason I didn't use a vector is that the struct that I'm coping to is already define, and I don't have control over it :(
>>

Arrha, i see :)

The "switch" will work though, it's just that the preproccesor will need a const at compile-time, for the substitution.


jm
http://counter.li.org
#313537

The FVWM wm -=- www.fvwm.org -=-

Somebody stole my air guitar, It happened just the other day,
But it's ok, 'cause i've got a spare ...
jjmac
LXF regular
 
Posts: 1996
Joined: Fri Apr 08, 2005 1:32 am
Location: Sydney, Australia


Return to Programming

Who is online

Users browsing this forum: No registered users and 2 guests