From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,37680a99b5e22b2b X-Google-Attributes: gid103376,public From: bobduff@world.std.com (Robert A Duff) Subject: Re: Shared Generic Instance Code Date: 1997/04/01 Message-ID: #1/1 X-Deja-AN: 229989621 References: <5hrkhkINN9ip@snoopy.cis.ohio-state.edu> Organization: The World Public Access UNIX, Brookline, MA Newsgroups: comp.lang.ada Date: 1997-04-01T00:00:00+00:00 List-Id: In article <5hrkhkINN9ip@snoopy.cis.ohio-state.edu>, david scott gibson wrote: >Hi. Could someone summarize the advantages and disadvantages of >having an Ada compiler that when compiling generic units generates >code that may be shared by multiple instances? ... Well, you pretty much listed the trade-offs. As far as implementation complexity: Probably the easiest thing is to macro-expand. Second easiest is to always share. I don't think that's a lot harder -- you just thunk-ize everything imaginable. But always-share is extremely inefficient in some cases. Most complex is of course to *sometimes* share. This is of course the most efficient, because you can make the trade-offs based on the individual situation. For example, suppose you have a generic with a "type T is range <>;" formal. The best thing might be to create one copy of the code for each size of integer that gets passed in. Ada 95 makes code sharing a little bit easier than Ada 83, because the contract model is fixed. One thing that makes code-sharing hard is exceptions: if inside the generic, you declare an exception, then the semantics is that each instance has a distinct exception. That's a bit of a pain if you're sharing code. The Ada 9X project considered allowing such exceptions to all be lumped into one, but that idea was rejected due to upward incompatibility. Ada 95 has several rules that are specifically intended to help out with code sharing. There are comments about that in the AARM. For example, the rule that says, if you say P'Access inside a generic body, and P is declared inside that same body, then the resulting access value can't escape to the outside. (The workaround is to declare P in the private part.) It is essentially impossible (IMHO) to share code for the *spec* of a generic. When I talk about code sharing, I mean sharing code for the bodies of instances. One issue with code-sharing is rep clauses. Suppose you have a generic formal type with discriminants. If the actual type has a rep clause that puts the discriminants in some weird place, then the instance is supposed to obey that. So you can't code-share, unless you're willing to pass in information about the layout, and have the generic use that information when referencing the discriminants. E.g. pass in a thunk. That's inefficient. Better to share only in the usual case, where there is no rep clause on the actual. But that adds complexity to the compiler. It's unfortunate that all compilers don't take the same view of sharing, because it really hurts portability. There are some styles of generic usage that work well if you can code-share, but generate horrendously huge executables if not, making those styles impractical on some compilers. At least for Ada 83, there exist compilers that always share, and that never share, and that sometimes share. In the sometimes-share cases, there are various restrictions on what can be shared, different for different compilers. - Bob