C++ identifier names generated by rtiddsgen are not absolute

2 posts / 0 new
Last post
Offline
Last seen: 6 years 2 months ago
Joined: 09/26/2018
Posts: 1
C++ identifier names generated by rtiddsgen are not absolute

I have come across a problem with namespaces in the C++ code generated by the rtiddsgen tool. I'll try to provide a simple (contrived, but nevertheless completely valid) example.

Suppose that I am using DDS to communicate with a number of devices. Each device supports one of several communication packet formats: for the matter of this example, only one of them is relevant, and we will call it simple_io. The packet in this communication scheme comprises a simple header and a data field. The header is always the same, but the data field differs from device to device. Based on this simple organization, I then come up with the following IDL file (again, contrived and simplified, but I believe that it illustrates my problem nicely):

module simple_io {
module headers {

struct BasicHeader {
  long id;
};

}; // module headers
}; // module simple_io


module device_communication {
module simple_io {

struct MyDevicePacket {
  ::simple_io::headers::BasicHeader header;
  sequence<octet> data;
};

}; // namespace simple_io
}; // namespace device_communication

The first module (that might be even packed away in a separate IDL and then #included) is devoted to the simple_io communication mechanism. It has a nested namespace "headers" that defines the BasicHeader structure which represents the header used in this communication scheme (there is only one header type in this case, but you can imagine other, more complex communication schemes with more than one header type, so it makes sense to pack them into a submodule).

After that follows the namespace devoted to device communication. It has sub-namespaces for each communication mechanism, again to keep things organized. Within the namespace "simple_io", there is a definition of a data packet for a specific type of a device ("MyDevice").

I hope this example makes sense up to here.

The problem is, the generated code (using the Traditional C++ API) does not compile:

example.h:124:13: error: ‘headers’ in namespace ‘device_communication::simple_io’ does not name a type
             simple_io::headers::BasicHeader   header ;
             ^

Omitting all content that is not relevant to the problem, the offending piece of the code essentially boils down to this:

namespace device_communication {
namespace simple_io {
  class MyDevicePacket {
    simple_io::headers::BasicHeader header;
  }
}}

It is quite clear what is going on: the compiler sees the "simple_io::headers::BasicHeader" identifier within a scope of a namespace named "simple_io" and thus interprets it as "::device_communication::simple_io::headers::BasicHeader". Of course, there is no "::device_communication::simple_io::headers" namespace, hence the error. The actual referenced structure should have been "::simple_io::headers::BasicHeader".

The essence of the problem is that the name emitted by rtiddsgen is a relative name. The structure should have been defined as

class MyDevicePacket {
  ::simple_io::headers::BasicHeader header;
}

Note the double colon preceding "simple_io".

If you look at the original IDL, you can see that I actually did try to refer to the BasicHeader structure with an absolute name, but rtiddsgen seems to strip the leading double colon, leaving only the relative name.

My simplified example could of course be reshaped in such a way as to circumvent that problem. But this is not always possible, as parts of the IDL code might be provided by third parties and then #included in the final IDL. Using relative names greatly increases the likelyhood of clashes, since a name defined on the top level potentially clashes with all identically named entities on all levels of the namespace hierarchy. So I believe that this problem needs to be properly resolved by using absolute identifiers in the generated code.

Offline
Last seen: 3 years 3 months ago
Joined: 11/23/2016
Posts: 6


Hello,

Thanks for reporting this issue, I've checked internally and this is a known issue (CODEGENII-609) which only happens when the root module is repeated inside of it. I also need to mention that there is another workaround that you can use that is to add an extra module on top of the root module (simple_io), however, the generated code won't contain the leading double colon, for example:

module extra {

module simple_io {
module headers {
 
struct BasicHeader {
   long id;
};

}; // module headers
}; // module simple_io

module device_communication {
module simple_io {

struct MyDevicePacket {
    ::simple_io::headers::BasicHeader header;
    sequence<octet> data;
};
}; // namespace simple_io
}; // namespace device_communication
}; // namespace extra

Regards,

Valentín