[aspectc-user] syntax question

Law, Colin colin.law at epid.eurotherm.co.uk
Tue Feb 12 12:57:15 CET 2002


> -----Original Message-----
> From: Olaf Spinczyk [mailto:olaf at ivs.cs.uni-magdeburg.de]
> Sent: 12 February 2002 10:31
> To: aspectc-user at aspectc.org
> Subject: Re: [aspectc-user] syntax question
> 
> 
> Hi,
> 
> On Tuesday, 12. February 2002 10:44, you wrote:
> > I have class A with member function virtual void a(), and 
> derived class B
> > which overrides a(). I wish to apply a before() operation 
> to each execution
> > of a(). So the pointcut can be
> > pointcut c() = execution("void %::a()");
> > However if a third unrelated class C also has member fn a() 
> then this will
> > be also be selected by the pointcut.  What I want to do is 
> select a() only
> > where it is a member of a class derived from A.  Does the 
> compiler support
> > this?  I have experimented with within() and base() but 
> suspect that these
> > are not supported yet, or maybe I just have the wrong syntax.
> 
> 'within(derived("A")) && execution("void %::a()")' is the 
> right pointcut for 
> your scenario. The only problem is that "within" in not included in 
> "0.4pre2". You will find this feature in the next release, 
> which will come 
> today :-)
> 
> here is the code (tested):
> -------------------------------------------------------------------
> #include <iostream.h>
> 
> aspect O
>  {
>    advice within(derived("A")) && execution ("void %::a()") :
>       void before ()
>       { cout << "before a()" << endl; }
>  };
> 
> class A
>  {
>    public:
>       int i;
>       virtual void a () {}
>  };
> 
> class B : public A
>  {
>    public:
>       void a () {}
>  };
> 
> class C
>  {
>    public:
>       void a () {}
>  };
> 
> int main ()
>  {
>    B b;
>    C c;
> 
>    b.a ();
>    c.a ();
>  }
> --------------------------------------------------------------
> ---------------
> The advice is only executed for b.c().
> 
> 
> > On a separate issue, once into the before() advice I wish to access
> > existing attributes and methods of A, is this possible?
> 
> Yes, it is... (tested as well)
> --------------------------------------------------------------
> ---------------
> class A;
> 
> aspect O
>  {
>    void access_A(A* aptr);
> 
>    advice that(aptr) && execution ("void %::a()") :
>       void before (A *aptr)
>       { access_A(aptr);
>       }
>  };
> 
> class A
>  {
>    public:
>       int i;
>       A() { i = 4711; }
>       virtual void a () {}
>  };
> 
> // B and C as show above
> 
> void O::access_A (A *aptr)
>  { cout << "before a(), i is " << aptr->i << endl;
>  }
> 
> // main as show above
> --------------------------------------------------------------
> ----------------
> 
> By the way, 'that("A")' or 'that(aptr)' has the same effect as 
> 'within(derived("A"))' in this example. So you can continue with your 
> experiments without waiting for the newest version.
> 
> The difference between 'derived' and 'that' is that 'derived' 
> statically 
> looks for the scope of the join points, while 'that' checks 
> an object type. 
> Sometimes this can be done statically (as in your case), but 
> sometimes a 
> run-time check must be generated.
> 
> The helper function access_A is needed to avoid cyclic access 
> relations. If 
> you have an <Aspect>.ah file and you want to access a class, 
> from which your 
> aspect is called, then you should have a separate <Aspect>.cc 
> file, which 
> includes the class header file. In the aspect header file 
> there must be a 
> forward declaration of the class.
> 
> I hope this helps,
> 
> Olaf

Excellent, that works well (or should I say that(aptr) works well).
I am having a little trouble getting the hang of the syntax, in the line
advice that(aptr) && execution ("void %::a()"): void before(A *aptr)
presumably 'that()' is getting its parameter from 'before(A* aptr)', which
does not seem intuitive.

I attempted to get the same effect using a pointcut declaration as follows,
using my class types

pointcut ini() = that( "CWnd" ) && execution("int %::OnInitDialog()");
advice ini() : void before( CWnd* pWnd ) {...}

I did not have all that much hope that I had got it right, but it compiled
in ac++ but generated uncompilable code, with 
   TestAspect::aspectOf ()->TestAspect::__advice_0 ();
appearing in the new OnInitDialog(), but
void __advice_0( CWnd* pWnd )
appearing in the aspect declaration.

On the requirement for the helper function access_A, I tried it without the
helper function, directly accessing the pointer in before() and it was OK.
Can you explain this issue in more detail?

Thanks for all the help, I hope you are finding my input useful also.

Colin Law



More information about the aspectc-user mailing list