CORBA 3.5b1 RTF Avatar
  1. OMG Issue

CORBA35 — Allowing Mutual Recursion for IDL Structures

  • Key: CORBA35-109
  • Legacy Issue Number: 8969
  • Status: open  
  • Source: Zuehlke Engineering ( Frank Pilhofer)
  • Summary:

    CORBA 2.4 introduced forward declarations for IDL structures
    and unions in support of recursive structures, deprecating the
    prior practice of anonymous types.

    Also allowed were sequences of forward-declared structures
    ("incomplete types"), which could then be used as members in
    defining the structure. Currently, it is only allowed to use
    incomplete types in the actual definition of the type itself.

    As an example in section 3.11.2.3 demonstrates, this does
    allow indirect recursion – but only if the incomplete types
    are nested, as in [first example]

    struct Foo;
    typedef sequence<Foo> FooSeq;

    struct Foo {
    struct Bar

    { FooSeq fs; }

    b;
    };

    Specifically not allowed – and this is the point of this
    issue – is the seemingly more intuitive definition of
    [second example]

    struct Foo;
    typedef sequence<Foo> FooSeq;

    struct Bar

    { FooSeq fs; }

    ;

    struct Foo

    { Bar b; }

    ;

    Currently, the spec says that, "sequence members that are
    recursive must refer to an incomplete type currently under
    definition," and thus Bar is not allowed to use FooSeq as
    a member.

    However, the second example is, in effect, no different than
    the first. In the first example, "Foo::Bar" is a well-defined
    stand-alone type that can be used elsewhere (e.g., as a
    structure member or operation parameter).

    If a developer intends to use both structures, the second
    example makes this much clearer, as it syntactically elevates
    "Foo::Bar" from a mere sub-type to an "independent" structure.

    Therefore, I would like to change the current wording of
    section 3.11.2.3 to allow the second example. A proposed
    update is below.

    This issue is all the more urgent because another available
    specification, the "Deployment and Configuration of
    Component-based Distributed Applications," depends on it,
    by using two IDL structures that mutually and indirectly
    recurse, effectively using [third example]

    struct Package;
    typedef sequence<Package> PackageSeq;

    struct Assembly;
    typedef sequence<Assembly> AssemblySeq;

    struct Package

    { AssemblySeq as; }

    ;

    struct Assembly

    { PackageSeq ps; }

    ;

    In reality, the IDL in question is a bit more complicated,
    using some intermediate structures, which makes rewriting
    the IDL without this mutual recursion impractical and
    non-intuitive – also because both "Package" and "Assembly"
    are meant to be potentially top-level, stand-alone items.

    Some might argue that the IDL restriction existed before
    the "Deployment" specification was adopted, and that CORBA
    should not be changed just because some later spec
    willingly (or rather, naively) used buggy IDL.

    So let me make some more arguments in favor of my request.

    First, as explained above, IDL already allows for indirect
    recursion. It just requires nesting.

    Second, defining structures as a "side-effect" of a member
    declaration is ugly, only marginally better than anonymous
    types. Allowing the type definition of a member to stand
    by itself is, in my opinion, much cleaner.

    Third, indirect recursion between non-nested types is no
    more difficult to implement in an ORB than indirect recursion
    between nested types.

    In fact, some existing ORB products already have no problem
    with indirect recursion, and are able to compile the IDL
    from the third example, resulting in correct code. The code
    works fine with Mico, TAO, JacORB and Combat, all of which
    apparently neglect to implement the check that "sequence
    members that are recursive must refer to an incomplete type
    currently under definition."

    OmniORB does issue a diagnostic, but simply removing the
    check, and making another trivial change to its IDL compiler,
    results in correct C++ code.

    Four, the existing IDL syntax, TypeCodes, CDR marshalling
    rules, and Interface Repository all allow indirect recursion
    to exist. In fact, it is already possible to create the
    above data types using the Interface Repository and
    TypeCode interfaces – as well as to create instances
    using DynamicAny, and to marshal them.

    With this background, I suggest to remove the statement
    that prevents indirect recursion between non-nested
    structures and unions.

    Proposed resolution:

    In section 3.12.2.3, change paragraphs (counting each IDL
    code example as a single paragraph) 10 to 12 (page 3-42)
    from

    If a recursive structure or union member is used,
    sequence members that are recursive must refer to
    an incomplete type currently under definition. For
    example

    struct Foo;
    typedef sequence<Foo> FooSeq;
    struct Bar

    { long value; FooSeq chain; // Illegal, Foo is not an enclosing }

    ; // struct or union.

    Compilers shall issue a diagnostic if this rule is
    violated.

    to

    If a sequence member of a structure or union refers
    to an incomplete type, the structure or union itself
    remains incomplete until the member's definition is
    completed. For example

    struct Foo;
    typedef sequence<Foo> FooSeq;
    struct Bar

    { long value; FooSeq chain; // Use of incomplete type }

    ; // Bar itself remains incomplete
    struct Foo

    { // ... }

    ; // Foo and Bar are complete

    Thank you for listening. Also thanks to Jeff Parsons
    and Boris Kolpakov from Vanderbilt University for
    researching this issue.

    We, the submitters of the "Deployment" specification,
    genuinely believe that indirect recursion is useful,
    and its lack (and having to work around) would take
    considerable value from the specification.

    I am uncomfortable arguing to change another spec
    to fix ours. But one spec has to change, and I believe
    that indirect recursion is a useful feature that already
    (unwillingly) exists in many ORBs, that it is no more
    problematic to implement than the existing means of
    recursion, and that the resulting data types are already
    valid when obtained from the TypeCode or Interface
    Repository interfaces.

    Considering the conflict of available specifications,
    I am tempted to flag this issue as urgent. Andrew, is
    that even possible, given that there is no active Core
    RTF?

  • Reported: CORBA 3.0.3 — Wed, 17 Aug 2005 04:00 GMT
  • Updated: Wed, 1 Feb 2023 21:59 GMT