[aspectc-user] Automatic #include insertion

arnd-hendrik.mathias at nefkom.net arnd-hendrik.mathias at nefkom.net
Thu Apr 3 00:34:02 CEST 2008


Hi,
thanks Olaf and Panu for all the hints. I didn't recognize the  
--no_line option, yet. It is very useful (at least if I come that far  
that an acc file is generated ;-).
I learned that ac++ works in a way, that modifies previous class  
definitions backwards, while including the modified .ah file itself  
"as is" (rather than introducing the needed code and includes to the  
source files without including the .ah file). As a following of this,  
the used resources are needed to be known before the first appearance  
of the modified classes.

So, a general design rule can be defined, that all headers declaring  
referenced entities shall be included first, before including headers  
declaring  any of the modified entities.

In the example this means that a.hh shall be included in the ah file  
before the test.hh which works perfect.

Zitat von olaf.spinczyk at cs.uni-dortmund.de:

> In order to solve the cycle problem, use a named class slice and move its
> definition into a different aspect header file. This new file should
> include a.hh (and neither test.hh nor test.ah). test.ah will only include
> the new aspect header file, which defines the slice. As a result, ac++
> will generate something like #include "new_file.ah" in test.hh, which in
> turn includes a.hh. -> no longer a cycle.

Doesn't this conflict with the main targets of AOP, to keep  
crosscutting concerns assembled together in one aspect rather than  
dividing them over separate entities or even files?
In this context I'd like to ask for a feature for ac++:

Wouldn't it be useful to allow for introducing slices defining static  
members inside of an aspect in the following way:

aspect A
{
    slice class B
    {
       public : static int b;
    };
    slice int B::b = 2;
    advice "C" : slice B;
};

This would aid keeping stuff of an aspect together rather than the  
current way, in which the aspect A is actually divided over three units:

slice class B { public : static int b; };

slice int B::b = 2;

aspect A { advice "C" : slice B; }


Best regards

Arnd-Hendrik



> Best regards,
>
> Olaf
>
>
>> Hi,
>> no, sorry, just a typo in the cited code. The original contains the
>> correct name.
>>
>> Panu Bloigu wrote:
>>> Hello.
>>>
>>>> test.hh:
>>>> class test {};
>>>
>>> This should probably be with the capital 'T':
>>>
>>> test.hh:
>>> class Test{};
>>>
>>> ---
>>>
>>> I quickly tested your code and found out that when ac++ generates the
>>> test.acc file, the declaration 'extern char a' is inserted to that
>>> file a few lines after the definition of the method Test::test(). This
>>> means that the variable 'a' isn't yet visible in the method
>>> Test::test().
>>>
>>> .acc files are the output of ac++ compiler. They can then be fed to
>>> your regular C++ compiler. I've found that it's sometimes very useful
>>> to take a look at the generated .acc files to see if the problem is in
>>> the code generated by ac++ and not in your own code. If you already
>>> didn't know this, the ag++ wrapper for ac++ deletes the .acc files
>>> after they have been processed by your C++ compiler, but you can
>>> instruct ag++ to leave them lying around with the option --keep_acc
>>> (in the SVN version this option seems to have been replaced with
>>> --keep_woven, or something similar).
>>>
>>> So as a conclusion, I suspect that there's a problem with the code
>>> generated by ac++. The AspectC++ compiler devs on this list might want
>>> to check this out. Just for reference, there's this code in test.acc,
>>> beginning at line 71:
>>>
>>> ============================
>>> class Test{  friend class ::Test1;
>>>    private:
>>>  public : static void test ( void )
>>> {
>>> std :: cout << "In Test::test ()" << std :: endl ;
>>> std :: cout << "a = " << a << std :: endl ;
>>> } ;};
>>> #endif /*TEST_HH_*/
>>> #endif //
>>> __ac_guard_C__Documents32and32Settings_work_Desktop_temp_Rojekti_test_hh__
>>>
>>> #ifndef A_HH_
>>> #define A_HH_
>>> extern char a;
>>> #endif /*A_HH_*/
>>> ============================
>>>
>>> I gave the --no_line option for ac++ to see error messages with line
>>> numbers of the .acc files instead of line numbers of the original
>>> source files.
>>>
>>>
>>>> test.cc:
>>>> int main ( int argc, char** argv ) { return 0; }
>>>>
>>>> a.hh:
>>>> extern char a;
>>>>
>>>> a.cc:
>>>> #include "a.hh"
>>>> char a = 'H';
>>>>
>>>> test.ah:
>>>> #include <iostream>
>>>> #include "test.hh"
>>>> #include "a.hh"
>>>>
>>>> aspect Test1
>>>> {
>>>>    advice "Test" : slice class
>>>>    {
>>>>       public : static void test ( void )
>>>>       {
>>>>          std::cout << "In Test::test ()" << std::endl;
>>>>          std::cout << "a = " << a << std::endl;
>>>>       };
>>>>    };
>>>>    advice execution ( "% main ( ... )" ) : before ()
>>>>    {
>>>>       Test::test ();
>>>>    };
>>>> };
>>>>
>>>> Here the test.hh include (for the Test class) is inserted
>>>> automatically (can be tested by removing the "a = "... line from the
>>>> aspect) while the a.hh include is not. In this example this leads to
>>>> "error: 'a' was not declared in this scope".
>>>>
>>>> Can anyone confirm this or am I doing something wrong here? Is this
>>>> behavior by a special purpose?
>>>> In the given example the consequence was, that I have to add the
>>>> #include line to the test.cc permanently, independently of whether I
>>>> use this aspect or not.
>>>> Best regards
>>>>
>>>> Arnd-Hendrik
>>>>
>>>>
>>>> _______________________________________________
>>>> aspectc-user mailing list
>>>> aspectc-user at aspectc.org
>>>> http://www.aspectc.org/mailman/listinfo/aspectc-user
>>>
>>>
>>>
>> _______________________________________________
>> aspectc-user mailing list
>> aspectc-user at aspectc.org
>> http://www.aspectc.org/mailman/listinfo/aspectc-user
>>
>>
>
>
>







More information about the aspectc-user mailing list