[aspectc-user] overloaded operator ++() and ++(int)
Olaf Spinczyk
Olaf.Spinczyk at informatik.uni-erlangen.de
Tue May 24 12:04:20 CEST 2005
Hi Hans,
Hans VB wrote:
> Hey,
>
> it seems to work if i use execution in stead of call (maybe because i am
> in main()), so ok...
>
> What bothers me now is the following :
> I want to select all constructions of objects of class B but not those
> that happen in/caused by operators.
> this is my operator ++(int) :
>
> B operator ++(int) {
> B tmp = *this;
> ++(*this);
> return tmp;
> }
>
> This doesnt return a reference because you'd better not return reference
> of local temp vars. What it does do is call a constructor when it
> returns tmp.
> I manage to filter out the construction of tmp, but not the one of this
> returned tmp :
>
> pointcut allRealConstructions() = construction("B") && !cflow(
> execution("% B::operator %(...)") );
>
> Any ideas would be greatly appreciated! (and quite urgently too - this
> is in fact for my thesis which has to be finished real soon ;-)
>
> Greets,
> Hans
the problem with cflow and the construction of the result object is that
the creation of a copy of the result object is (1) a client-side
activity and, thus, not in the cflow of your operator++. Furthermore,
(2) the compiler is allowed to avoid the execution of the copy
constructor. This is illustrated by the following example:
---
#include <iostream>
using namespace std;
class B {
public:
B() {
cout << "B()" << endl;
}
B (const B&) {
cout << "B(const B&)" << endl;
}
B& operator = (const B&) {
cout << "operator = (const B&)" << endl;
}
};
B f () {
B tmp;
return tmp;
}
void g (const B& b) {}
int main () {
f ();
B result = f (); // no copy constructor executed!
g (f()); // no copy constructor executed!
B x (result); // here the object is created with the copy constructor
}
---
If you compile it with g++ 3.3 the output is:
B()
B()
B()
B(const B&)
Although f() is much like your operator ++ the copy constructor is never
executed.
To summarize: It is (1) not guaranteed that the copy constructor will be
executed. If it is executed, the execution is not in the cflow of your
operator++ (2).
Now AspectC++ come into play: If you weave execution advice for the
operator ++ the generated wrapper function will allocate memory space
for the result object and initialize it with the result of the orginal
(wrapped) function by using the copy constructor. This copy construction
can't be avoided by compiler optimizations. This copy constructor
execution is *in* the cflow! However, this temporary result object is
then return by the wrapper function to the caller, which might again
result in a copy constructor execution. This (second) copy construction
is not in the cflow! That's how it is currently implemented. Can you
confirm that the copy constructor is executed twice in your code?
From the language point of view I would prefer the copy construction of
the result object to be in the cflow of the call, but not in the cflow
of the execution. This brings us back to the problem with call advice
for operator ++(int) :-(. I think it would be best to with fixing the
call advice problem. Do you agree?
Best regards,
Olaf
More information about the aspectc-user
mailing list