[aspectc-user] How to include files with aspectC++

Olaf Spinczyk Olaf.Spinczyk at informatik.uni-erlangen.de
Tue May 18 14:24:36 CEST 2004


Hi,

Mikael Björk wrote:
> Hi again
> 
> I have carefully studied the weaved code and managed
> to condense the problem. So I pose a more detailed
> question at the end.
> 
> 
>>To avoid problems 
>>follow 
>>these rules:
>>
>>1. Always use include guards in your header files
>>
>>2. Make sure that no header file depends on the
> 
> inclusion of other
> 
>>   include files. It has to be valid (Aspect)C++
> 
> code on its own.
> 
> 
> I'm afraid I don't understand rule number two. Do
> you mean that no header files should include other
> header files (and thus be valid on their own) or do
> you mean that if a header file requires something
> from another header file, it should include that
> file directly (instead of including a third file
> which includes the desired header)?

Of course, include files are allowed include other include files. What I 
mean is the following: If a header file C needs something from another 
include file B, it should include this file. It doesn't matter if B is 
included directly or indirectly.
However, C should not rely on the fact that files, which include C, 
include B first.

Don't do this (a<--b means a includes b):

A <-- B
   <-- C (needs B, but doen't include it)

Do that instead:

A <-- B
   <-- C <--B (C gets what it needs, the include guard is needed, because
               B is included twice)

I hope that my point is clear now.

> I should point out that the system I'm working on is
> written in C, but since the aspect weaver introduces
> C++ code, we compile the program with g++.

I would be interested in the size of your system (number of files, lines 
of code, number of aspects). Could you give me an idea? Do you have 
performance problems with ac++?

> Now to a condensed description of the problem, first
> a number of files (severely cropped):
> 
> ===============================================
> // BufferManagerInterface.h
> 
> struct Btable {int stuff};
> ===============================================
> // USMA.ah
> 
> #include "hp2pl-w-similarity.h"
> 
> aspect USMA
> {
>   advice "transactionInformation" : int updateWait;
>   advice "Btable" : int ID;
> };
> ===============================================
> // hp2pl-w-similarity.h
> 
> #include "MMCinterface.h"
> 
> struct transactionInformation {int stuff};
> 
> void initializeThread();
> ===============================================
> // MMCinterface.h
> 
> void stuff();
> ===============================================
> // hp2pl-w-similarity.ah
> 
> #include "hp2pl-w-similarity.h
> #include "MMCinterface.h"
> 
> aspect hp2pl-w-similarity.h
> {
>   initializeThread();
>   do-other-stuff-with-MMC-for-example();
> };
> ===============================================
> 
> The problem is that USMA is weaved in before BufferManagerInterface.h and USMA.ah includes hp2pl-w-similarity.h.
> 
> hp2pl-w-similarity.h in turn includes MMCinterface.h
> 
> Unfortunately the aspect hp2pl-w-similarity needs the information in hp2pl-w-similarity.h (and thus includes it), but when hp2pl-w-similarity is weaved into the code right before MMCinterface is included, the function initializeThread() has not been declared yet.
> 
> This is the order in which everything occurs in the weaved file (indentation indicates a level of inclusion and I have removed everything which is unreachable due to inclusion guards):
> 
> -----------------------------------------------
> 
> forward_declaration_stuff_of_USMA;
> 
> // USMA.ah
> 
>   // hp2pl-w-similarity.h
> 
>     // hp2pl-w-similarity.ah
> 
>     aspect hp2pl-w-similarity.h
>     {
>       initializeThread();
>       do-other-stuff-with-MMC-for-example();
>     };
>     // MMCinterface.h
> 
>     void stuff();
> 
>   struct transactionInformation {int stuff};
> 
>   void initializeThread();
> 
> aspect USMA
> {
>   advice "transactionInformation" : int updateWait;
>   advice "Btable" : int ID;
> };
> 
> // BufferManagerInterface.h
> 
> struct Btable {int stuff};
> 
> -----------------------------------------------
> 
> As you can see initializeThread() is used before it is declared. 
> 
> Since I do not have knowledge of ac-internals I do not understand why aspect hp2pl-w-similarity is weaved in before MMCinterface.h but not before hp2pl-w-similarity.h. If this was not so, the program would work.
> 
> So my question is whether this is a bug or a feature? Is there some way around this problem? (Except for including MMCinterface in USMA.ah)
> 
> /Mikael

You have to know that whenever an aspect introduces code into a class 
(here Btable and transactionInformation) the aspect header is included 
in front of the affected class automatically. This is to make sure that 
data types needed by the introduced code are known when the introduction 
is compiled. Therefore, hp2pl-w-similarity.h includes USMA.ah and vice 
versa.

At the moment I don't see a reason why USMA.ah includes 
hp2pl-w-similarity.h. So maybe you can solve your problem by simply 
removing this #include directive in USMA.ah.

In such a situation the aspect header always "wins". That means that 
hp2pl-w-similarity.h will be compiled before the aspect in USMA.ah. As 
BufferManagerInterface.h includes USMA.ah after the code manipulation, 
struct Btable becomes the last defined thing in your code. So far the 
order is reasonable, but I also don't understand why the code from 
aspect hp2pl-w-similarity is compiled before the definitions from 
hp2pl-w-similarity.h. I tried to reproduce the problem but here the 
order was different and the code compiled without any problems. My 
impression is that some important code is missing. Don't you have any 
advice defined in aspect hp2pl-w-similarity? This might change the file 
order and explain why I can't reproduce your problem.

Could you send my your code (e.g. a tar.gz archive) and tell me which 
ac++ you are using?

BTW, aspects can also affect joinpoints in files included in front of 
the aspect definition in the aspect header. For example:

==============
// Test.ah

<= a forward declaration of the aspect is automatically generated here
#include "A.h" <= this (class "A") can be used in the introduction
#include "B.h" <= this file is affected (class "B")
#include "C.h" <= this cannot be used in the introduction, because we
                   can't guarantee that it is known in B.h

aspect Test {
   // the introduction
   advice "B" : A aobj; <= use only A and the aspect forward decl.
};
==============

You can use this feature to sort the files a little bit.

I hope this helps. Please send me your comments.

Olaf



More information about the aspectc-user mailing list