[aspectc-user] Re: [aspectc-user] intercepting flow of executio Re: [aspectc-user] intercepting flow of execution of the method declaredinside aspect

Olaf Spinczyk Olaf.Spinczyk at informatik.uni-erlangen.de
Thu May 27 12:42:22 CEST 2004


Hi,

Bartosz Blimke wrote:
>>Here is an example of some working AspectC++ code that disables the
>>advice for the execution of "func()" when "func()" was called from the
>>aspect member function "run()".
>>
>>=======main.cc=========
>>#include <stdio.h>
>>
>>void func () {
>>   printf ("func\n");
>>}
>>
>>int main () {
>>   func ();
>>}
>>
>>====CFlowTest.ah========
>>#ifndef __CFlowTest_ah__
>>#define __CFlowTest_ah__
>>
>>aspect CFlowTest {
>>   pointcut methods() = execution("% func()");
>>
>>   void run(AC::Action &action) {
>>     action.trigger();
>>   }
>>
>>   advice methods() && !cflow(execution("% CFlowTest::run(...)")) :
>>around () {
>>     run(tjp->action ());
>>   }
>>
>>};
>>
>>#endif // __CFlowTest_ah__
>>
>>I hope that this is what you wanted to achieve. Please tell me if I'm
>>wrong.
>>
> 
> 
> Hello Olaf,
> 
> Sorry, for not being clear in the first mail, I will try
> next time to write more clear what I want.
> This example that you wrote me is exactly what I want to use.
> Anyway, I'm not able to compile it, I have still the same
> compiling error. I'm using VC++ .NET 2003 with AspectC++ Add-In: 1.0.7
> (Mar 19 2004) and that means ac++ ver 0.8.
> Is this the problem of 0.8 version ?
> 
> 
> Linking...
> main.obj : error LNK2005: "public: __thiscall `private: void __thiscall
> CFlowTest::run(struct AC::Action &)'::`3'::Trigger::Trigger(void)"
> (??0Trigger@?2??run at CFlowTest@@AAEXAAUAction at AC@@@Z at QAE@XZ) already
> defined in TestAspectProject_LinkOnce.obj
> main.obj : error LNK2005: "public: __thiscall `private: void __thiscall
> CFlowTest::run(struct AC::Action &)'::`3'::Trigger::~Trigger(void)"
> (??1Trigger@?2??run at CFlowTest@@AAEXAAUAction at AC@@@Z at QAE@XZ) already
> defined in TestAspectProject_LinkOnce.obj
> Debug\TestAspectProject.exe : fatal error LNK1169: one or more multiply
> defined symbols found
> 
> 
> Greets,
> 
> Bartosz Blimke

I tried the code with 0.8 and 0.8.1 under Linux and it worked. The 
problem is specific for the Visual C++ compiler :-(. Now I know what's 
going on ...

Local classes (class defined within a function) are not handled 
correctly by VisualC++ and lead to the linker problem that you 
experienced in this example. We already reported the problem to 
Microsoft (a few months ago), but it will take some time until the 
problem will be fixed.

As a workaround ac++ uses different code generation patterns if the 
back-end compiler has this problem. The command line option 
"--problem_local_class" is used to enable this workaround and it is 
enabled by default in the Windows version of ac++.

However, the code generation pattern used for the joinpoints where a 
cflow is entered does not regard the option "--problem_local_class". 
This is a bug in ac++ and I'll try to fix it immediately.

Our test cases show that cflow does not always fail under Windows. 
Therefore, I'm optimitic that the following workaround will help you:

Move the implementation of your run() function from the aspect header 
into a *.cpp file which includes the aspect header explititly.

aspect header:

aspect Aspect {
   void run(AC::Action &action);
   ...
};

Aspect.cpp:

void Aspect::run (AC::Action &action) {
   action.trigger();
}

The local class will now be generated only in Aspect.cpp and the linker 
can't complain that it is defined twice.

I hope that helps,

Olaf



More information about the aspectc-user mailing list