[aspectc-user] Automatic #include insertion

Panu Bloigu panu.bloigu at gmail.com
Thu Apr 3 10:25:16 CEST 2008


Hello.

Just to answer this question:

olaf.spinczyk at cs.uni-dortmund.de wrote:
> Hi,
> 
> the problem is (once again) an include cycle. I only wonder, why ac++ does
> not complain about it. Which version are you using?

The version I used was 1.0pre3. I tested this later with the SVN version 
and it indeed warns about the presence of the include cycle.


Also, for Arnd-Hendrik, if this hasn't already come up, Olaf posted an 
illustration of the include cycle problem on the list on 2007-11-17 that 
you might find worth taking a look at: 
http://aspectc.org/pipermail/aspectc-user/2007-November/001188.html. See 
the pdf attachments in that message.


> The point is that you introduce a new function into the class Test (define
> in test.hh. Therefore, ac++ generates #include "test.ah" within test.hh.
> The reason is that the introduced code shall be able to, for instance, the
> vaiable 'a'. However, as you include test.hh in test.ah there is an
> include cycle. Due to the include guards, this doesn't lead to fatal
> problems, but eventually test.hh is expanded before a.hh (this is the
> include-order in test.ah).
> 
> 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.
> 
> 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