Can an Ada Variant Record be binary compatible to a C++ union?
Asked Answered
I

4

6

I am designing a communication middleware for use in an application which has a module in Ada and many modules in C++ which communicates passing parameters (scalar values) and structures. The application runs in MS Windows XP and Windows 7, the C++ part is being developed in MSVC++ 2008, the Ada part is being developed using GPS/GNAT. Ada version is 1995 but we're in the middle of a compiler migration (newer version of GPS/GNAT) with the possibility of using newer Ada spec.

The middleware is being written in C++ and I would like to use a union type containing all types that are passed between modules so I won't need to specify one put/get function for each type that is used on the system.

The question is, are C++ unions binary compatible to Ada variant records? In other words, if I pass a C++ union to Ada code will it be able to read it as a Variant record? (and vice-versa)

I think that for this to be possible some adjustments will be necessary... (Eg.: C++ unions do not contain a member which describes its content while Ada variant records do)

Indreetloire answered 3/11, 2011 at 11:52 Comment(2)
You are probably going to need to specify platform, compilers etc.Wedlock
Thanks, just added more information about our environment.Indreetloire
S
8

Possibly.

Ada 2005 provides the Unchecked_Union pragma which allows a program to "[specify] an interface correspondence between a given discriminated type and some C union. The pragma specifies that the associated type shall be given a representation that leaves no space for its discriminant(s)."

From my reading of the RM section, one declares an Ada type with the discriminant(s) needed to define a variant record, but no storage space is allocated for the discriminant(s). I take it this means on the Ada side that the discriminant cannot subsequently be referenced. (There are other restrictions as well, like all the fields must be C-compatible, see RM B.3.3 for more info.)

I've never used this pragma, and I can't help but think that it will require some experimentation to get it to (hopefully) work with your system. Good luck!

Suchta answered 3/11, 2011 at 13:4 Comment(2)
Some of the experimentation will be to find out whether you need to tell GNAT to lay the records out the way MSVC++ expects, and if so how. GNAT understands GCC's conventions, of course; so long as you restrict yourself to C unions and straightforward types it shouldn't be too bad.Wellbeloved
GCC on Windows conforms to the platform C ABI, so GNAT on Windows should be ABI compatible with MSVC++.Larrisa
L
5

Yes.

Ada is compatible with C/C++ Unions. See here for how to do it (pdf) In particular Page 5 shows how to do it with Unions & Tags. It should be the same for using Discriminant records. (Caveat: it is probably not the compiler you are using, but i would be very surprised if yours didnt behave the same way!)

Longspur answered 3/11, 2011 at 14:41 Comment(7)
I think you're a little optimistic about the expectation that one can expect different Ada/C/C++ compilers to handle this with no great concern, but it is a helpful guide to the problem.Suchta
@Marc My Optimism is based on the fact that Ada compilers should be validated, so they should be able to do the same things (even if not equally well!)Longspur
It's not the Ada side I'm concerned about, it's the field layout and linking minutia amongst different compilers that colors me skeptical (of optimism :-). I'm no stranger to bindings, even sharing data structures between GNAT and gcc requires care.Suchta
The Green Hills document you reference only offers any promises provided the Ada, C and C++ compilers all come from Green Hills. AdaCore take a similar position (it may be easier for them since the backend is GCC). Also, I don't see anything on page 5 about data structures??Wellbeloved
@SimonWright Page 5 by pdf, Page 4 by the actual number on the page.Longspur
@NWS We use GNAT here for Ada and cl (MSVC++ 2008) for C++. I'll check here if GNAT has some documentation corresponding to the document you pointed non the answer. Other than that, I'll have to make some tests here to prove, at least for a limited set of types and structures, that there'll be compatibility at the binary level (which I find not much safe as I might find an incompatible type/structure later on...)Indreetloire
@Indreetloire As Marc said, The unknown is how to specify the C++ structures, After you know that, you should be able to make the Ada match.Longspur
H
3

As MSalters mentioned, it won't work unless the C union for some reason contains a field designating the variant. As this isn't required in C, it won't often work. However, since you control the implemeation of that C type, you can make it work. Just be sure to have a field right before the union that designates which union is being used.

To make it fully binary-compatible with your C union-bearing struct, you will probably need to go with a simple Ada record type, along with a record representation clause to make sure the fields are laid out in the same places your C compiler happens to put them. And yes, that does leave you vulnerable to C compiler changes causing layout changes. You can try to protect against that with bitfields in your C code, but they aren't powerful enough to really lay things out the way Ada record rep clauses can. That's one of the reasons we prefer to use Ada for low-level work.

I should mention that, when last I checked, the Windows version of Gnat was not linker-compatible with VisualStudio binaries. The only way I know of to get those two compilers to work together is to put the entire interface in a DLL. Otherwise, you will probably either need to use GCC to build your C++ system, or use some other Ada compiler, like ObjectAda.

Humberto answered 3/11, 2011 at 13:50 Comment(3)
"As MSalters mentioned, it won't work unless the C union for some reason contains a field designating the variant." Maybe I could do this with a struct like: struct foo{ some_tag_type tag; union{ ... } my_union; } ??Indreetloire
@guarita see my answer for a useful link - i think you are on the right track with this idea.Longspur
You should be able to get it to work at the language level, see answers by Marc C and NWS. I have to say that without something to say what sort of message it is it's going to be hard to decide what to do with it, but that's a system problem!Wellbeloved
L
2

No. As you state yourself, Ada variant records contain a tag field. The C union does not have that. (At least not in MSVC++ and GCC - it's allowed by ISO C.)

Larrisa answered 3/11, 2011 at 12:34 Comment(1)
Ahm, yes, but my question is if it is possible to make the C unions be compatible with Ada's Variants with some additional work not plug-n-play. I already expected to have some trouble to adapt the C part to binary-talk to the Ada code.Indreetloire

© 2022 - 2024 — McMap. All rights reserved.