Book a Demo

Author Topic: code generation and compiling the generated code  (Read 6156 times)

Timothy F. Brown

  • Guest
code generation and compiling the generated code
« on: April 01, 2002, 10:21:00 am »
I am new to UML and I am trying to understand how to go from model to compiling code.  I implemented a two class static model.  The two classes A and B have a bidirectional 1:1 association.  When I generated the Java it compiles just fine in a JBuilder project.  However when I generated the C++ it didn't compile, because A.h included B.h, but B.h which had a pointer to an A didn't include A.h.  Which means the B class didn't compile, because it didn't know about A.  Also if you include A in B you get some kind of circular compile error.  What am I missing or what am I doing wrong?

Here is the important part from A.h...
#include "B.h"

class A
{

public:
     A();
     virtual ~A();
     A( const A& theA);

     B * m_B;
};

Here is the relevant part of B.h...

class B
{

public:
     B();
     virtual ~B();
     B( const B& theB);

     A * m_A;
};

ronnie

  • EA User
  • **
  • Posts: 81
  • Karma: +0/-0
    • View Profile
Re: code generation and compiling the generated co
« Reply #1 on: April 01, 2002, 03:36:50 pm »
To avoid the circular compilation you need something like:

#ifndef A_H
#define A_H

HEADER CODE HERE

#endif


to make sure that files don't get included twice - I guess EA doesn't generate these automatically, but then we can't expect it to generate our entire program automatically can we?

But, I guess this might be an easy addition!

Ronnie
Ronnie

javelin5

  • EA User
  • **
  • Posts: 32
  • Karma: +0/-0
    • View Profile
Re: code generation and compiling the generated co
« Reply #2 on: April 02, 2002, 10:35:29 am »
Sorry I didn't use my registered account name to post originally.

As you can see EA correctly does #define the header.

Here is the generated A.h and B.h, everything.  It still doesn't compile.  It specifically doesn't like the B.h(which doesn't include A.h).  Even if you include A.h it doesn't compile.  This works in Java, but what is the problem with the C++ code and how do you overcome the problem.

///////////////////////////////////////////////////////////
//
//  A.h
//  Implementation of the Class A
//  Generated by Enterprise Architect
//  Created on:      14-Mar-2002 13:40:46
//  Original author: Timothy F. Brown
//  
///////////////////////////////////////////////////////////
//  Modification history:
//  
//
///////////////////////////////////////////////////////////


#if !defined(A_A87FAFFA_F3B3_4f6d_A2C3_A842F61D1ADC__INCLUDED_)
#define A_A87FAFFA_F3B3_4f6d_A2C3_A842F61D1ADC__INCLUDED_

#include "B.h"


class A
{

public:
     A();
     virtual ~A();
     A( const A& theA);

     B * m_B;
};

#endif // !defined(A_A87FAFFA_F3B3_4f6d_A2C3_A842F61D1ADC__INCLUDED_)

///////////////////////////////////////////////////////////
//
//  B.h
//  Implementation of the Class B
//  Generated by Enterprise Architect
//  Created on:      14-Mar-2002 14:02:00
//  Original author: Timothy F. Brown
//  
///////////////////////////////////////////////////////////
//  Modification history:
//  
//
///////////////////////////////////////////////////////////


#if !defined(B_D889A470_61D2_4dd8_9A84_F4DC17CBC2C3__INCLUDED_)
#define B_D889A470_61D2_4dd8_9A84_F4DC17CBC2C3__INCLUDED_



class B
{

public:
     B();
     virtual ~B();
     B( const B& theB);

     A * m_A;
};

#endif // !defined(B_D889A470_61D2_4dd8_9A84_F4DC17CBC2C3__INCLUDED_)
Timothy F. Brown

ronnie

  • EA User
  • **
  • Posts: 81
  • Karma: +0/-0
    • View Profile
Re: code generation and compiling the generated co
« Reply #3 on: April 02, 2002, 11:34:32 am »
I see what's going on here...

Firstly, when you put in a '#include "a.h"' in the 'b.h' file it goes off and looks in b.h and then tries to include a.h (which has already done the #define) and exits without doing anything then goes through the rest of b.h and finds an A class in use which hasn't finished being defined yet - hence the error.

The way around this little anomaly is to pre-declare the classes either before the class that has a pointer to them or in the class header before including anything else:

Either:
<a.h>
...
class A;

#include "b.h"

class A
{
   ...
};
...

<a.h>
...
class B;

#include "a.h"

class B
{
   ...
};
...


or just before the class definition do something like:

class B;
class A
{
 B *m_B;
};


class A;
class B
{
 A *m_A;
};


It shouldn't be too difficult for Geoff & the boys to implement one of these optionally in EA, although I don't know how often it would come up and it might be highlighting something that would ideally be done a different way.

Hope this has helped

Ronnie
Ronnie

javelin5

  • EA User
  • **
  • Posts: 32
  • Karma: +0/-0
    • View Profile
Re: code generation and compiling the generated co
« Reply #4 on: April 02, 2002, 12:40:07 pm »
I would of thought that bi-directional association while maybe not common would not be too uncommon.
Timothy F. Brown

javelin5

  • EA User
  • **
  • Posts: 32
  • Karma: +0/-0
    • View Profile
Re: code generation and compiling the generated co
« Reply #5 on: April 02, 2002, 12:53:49 pm »
Okay I made these modifications and they both work.  I think it is just a matter of them choosing which they want to implement more.

Case #1 compiles:  Can someone explain how the class A in B.h and the class A in the A.h end up being the same?

Case #2 compiles:  When you include A.h in B.h you have to predeclare both class A and Class B.

Well hopefully someone official responds to this topic.

Case #1
A.h

#include "B.h"

class A
{

public:
     A();
     virtual ~A();
     A( const A& theA);

     B * m_B;
};

B.h

class A;

class B
{

public:
     B();
     virtual ~B();
     B( const B& theB);

     A * m_A;
};

Case # 2
A.h

class B;

#include "B.h"

class A
{

public:
     A();
     virtual ~A();
     A( const A& theA);

     B * m_B;
};

B.h

class A;

#include "A.h"

class B
{

public:
     B();
     virtual ~B();
     B( const B& theB);

     A * m_A;
};
Timothy F. Brown

ronnie

  • EA User
  • **
  • Posts: 81
  • Karma: +0/-0
    • View Profile
Re: code generation and compiling the generated co
« Reply #6 on: April 03, 2002, 07:50:33 am »
They end up being the same because they have the same name in the same namespace/scope.

It's like saying to the compiler 'Hey, remember this name for a class and I'll tell you about the detail later'
In the same way you can pre-declare functions (actually all class definitions have function declarations unless you embed the function body inside the class) like:

void func();

<CODE...>

void func()
{
 <Function Body>
}


If you try to dereference the pointer to the pre-declared class then there will be problems because the compiler doesn't know about the detail (size of class, members etc.) - that's why you HAVE to use a pointer in these cases!

Anyway, hope I helped - I've enjoyed it.

Ronnie
Ronnie

javelin5

  • EA User
  • **
  • Posts: 32
  • Karma: +0/-0
    • View Profile
Re: code generation and compiling the generated co
« Reply #7 on: April 03, 2002, 01:26:06 pm »
Thanks, I understand what is going on now.  I would just like to here if this will be changed, so it compiles.  Will I have to watch out for bi-directional associations and fix this in the code?  I'm OK with this because there must not be much need for bi-directional associations.
Timothy F. Brown