[aspectc-user] multiple definition errors for "global" variables

Olaf Spinczyk Olaf.Spinczyk at informatik.uni-erlangen.de
Fri Feb 4 21:47:22 CET 2005


Hello Hans,

Hans VB wrote:

> Hello,
>
> Olaf Spinczyk wrote:
>
>> I just tried logging to an ofstream (in ACDT) and it worked. Here is 
>> my code:
>>
>> ---main.cc:
>> #include <stdio.h>
>>
>> int main () {
>>    printf ("Hello Hans ;-)");
>>    return 0;
>> }
>> ---
>>
>> ---Trace.ah:
>> #ifndef __Trace_ah__
>> #define __Trace_ah__
>>
>> #include <fstream>
>> using namespace std;
>>
>> extern ofstream out;
>>
>> aspect Trace {
>>    pointcut to_trace () = execution ("% main(...)");
>>    advice to_trace () : around () {
>>        out << "before " << JoinPoint::signature () << endl;
>>        tjp->proceed ();
>>        out << "after " << JoinPoint::signature () << endl;
>>    }
>> };
>>
>> #endif // __Trace_ah__
>> ---
>>
>> --- Trace.cc:
>> #include "Trace.ah"
>>
>> ofstream out ("logfile");
>> ---
>>
>> I used an ordinary ACDT managed make project. When I run the compiled 
>> application the logfile is created as expected.
>>
>> Please check if there is a relevant difference between my example and 
>> your code.
>>
>> Olaf
>
>
> I had understood to put the aspect definition also inside the .cpp 
> file. This way it works perfectly (if the #ifndef ... - guards are 
> applied well). Thanks!
>
> To avoid using a global variable, I noticed it's also possible to 
> declare ofstream (as private for example) and to define it in  
> before-advice which triggers on the main()-function of my program. I 
> guess this would be the only way if I would want to avoid global 
> variables, since aspects don't have a constructor, or do they? At 
> least my tries to include a constructor(/destructor) didn't have any 
> influence at all.
>
> Greets,
> Hans
>
aspect instances are of course also constructed. If you implement the 
aspectof() function you even have to instantiate them on your own. In 
your case, where the aspect is instantiated implicitly, you can define a 
default constructor (no arguments) and a destructor. Here is an example 
how you can define your output stream as an attribute of the aspect, 
which is initialized by the aspect's constructor:

aspect Trace {
    ofstream out;
    pointcut to_trace () = execution ("% main(...)");
    advice to_trace () : around () {
        out << "before " << JoinPoint::signature () << endl;
        tjp->proceed ();
        out << "after " << JoinPoint::signature () << endl;
    }
    Trace () : out ("logfile2") {}
};

If you implement your aspect like this you, don't need a global 
"ofstream out("...")" object and the Trace.cc file anymore.

Olaf

PS: Keep in mind that implicitly generated aspect instances are 
singletons, i.e. they are also globals.




More information about the aspectc-user mailing list