IDL and C++ generation

4 posts / 0 new
Last post
Offline
Last seen: 11 years 1 month ago
Joined: 01/07/2013
Posts: 15
IDL and C++ generation

Hi everybody,

I found some issues in IDL to C++ generation. For example if I have defined in the IDL two struct like these:

struct alpha{
  long x;
  beta y;
}

struct beta{
  long z;
}

The generation process (rtiddsgen) end correctly but the C++ code cannot compile because the order of the symbol is invalid (it cannot find the symbol beta). If I declare the struct beta before the struct alpha all works fine.

I really have to check always the order of the structs?
Why the code generation ends correctly but generates wrong (not compilable) code?

For the same reason I cannot define a struct like this:

struct alpha{
  long x;
  alpha y;
}

Or something like this:

struct alpha{
  long x;
  beta y;
}

struct beta{
  long z;
  alpha k;
}

Is there a way to define relations like these and generate some good C++ code?

Thanks

Steve

Gerardo Pardo's picture
Offline
Last seen: 3 weeks 1 day ago
Joined: 06/02/2010
Posts: 601

Hello Steve,

I agree that rtiddsgen could/should be more explicit about generating warnings and/or code that will nto compile or will cause problems...

There are two issues here:

  1. Using a type before it is declared (this has a solution, see below)
  2. Self referencing (directly or indirectly) types (this is not supported, see below)

(1) Using a type before it is declared (this has a solution)

The fact that you cannot do something like:

struct alpha {
    long x;
    beta y;
};

struct beta {
    long z;
};
... is really more of a limitation of the C/C++ language.  C/C++ require that at the time a type such as the struct alpha is  declared, the data-types necessary to determine the  storage of all the members are already declared, which is not the case above.
 
Solution:  To get this to work in C/C++ you can either declare the types in the opposite order, or refer to the type via a pointer. That is, in C/C++ the following will compile:
struct beta;
struct alpha {
    long x;
    beta *y;
};

struct beta {
    long z;
};

You can write IDL that will cause the above C/C++ code to be generated using the directive //@copy-c-declaration as shown below:

//@copy-c-declaration struct beta;

struct alpha {
  long x;
  beta *y;
};

struct beta {
  long z;
}; 

(2) Self referencing (directly or indirectly) types  (this is not supported)

Types that are directly self-referencing such as:

 struct alpha { 
    long x; 
    alpha *y; 
}; 

Or indirectly self-referencing like:

struct alpha {
    long x;
    beta *y;
};

struct beta {
    long z;
    alpha *k;
};

Are not allowed for publish/subscribe via DDS. You could trick rtiddsgen into generating code that will compile using directives like the //@copy-c-declaration but even if it compiles you will get problems at run-time when the system tries to determine things like the maximum serialized data size...

Gerardo

Offline
Last seen: 11 years 1 month ago
Joined: 01/07/2013
Posts: 15

Thanks a lot Gerardo! I've tryed the (C/C++) forward declaration to solve my problem. I use many sequences in my IDL, and this kind of solution seems not works for:

//@copy-c-declaration struct beta;

struct alpha {
  long x;
  sequence<beta> y;
};

struct beta {
  long z;
}; 

Is there a way to use forward declaration with sequences?

Thanks

Steve

 

Gerardo Pardo's picture
Offline
Last seen: 3 weeks 1 day ago
Joined: 06/02/2010
Posts: 601

Hi Steve,

Yes it can be done with a sequence as well. But you need to forward-declare the sequence type and refer to it via a pointer within the containing structure as shown below:

//@copy-c-declaration struct betaSeq;

struct alpha {
  long x;
  sequence<beta> *y;
};

struct beta {
  long z;
}; //@top-level false

Gerardo