Craig Ringer created THRIFT-4484:
------------------------------------

             Summary: C++ codegen invalid for optional self-membership
                 Key: THRIFT-4484
                 URL: https://issues.apache.org/jira/browse/THRIFT-4484
             Project: Thrift
          Issue Type: Bug
          Components: C++ - Compiler
    Affects Versions: 0.11.0
         Environment: Thrift 0.10.0 tested, but I don't see a change in 0.11.0. 
Fedora 25. gcc 6.4.1. x86_64.
            Reporter: Craig Ringer


Support was added for self-referential objects in in 
[https://github.com/apache/thrift/pull/84] "Tree/Recursive struct support in 
thrift".

 

The tests cover objects that are co-recursive, objects that have lists of 
themselves, etc. But there's no test for optional self-containment e.g.

{{{
struct RecSelf {
   1: i16 item
   2: optional RecSelf 
 }
}}}

This works fine for languages like Java and Go. But in C++ it generates 
nonsensical code that cannot compile because it contains a by-value member of 
its self and a separate {{isset}} member.

For example, from opentracing jaeger's IDL:

{{{
struct Downstream {
    1: required string serviceName
    2: required string serverRole
    3: required string host
    4: required string port
    5: required Transport transport
    6: optional Downstream downstream
}
}}}

code-generation produces

{{{
class Downstream {
 public:
 
  /* blah elided blah */

  virtual ~Downstream() throw();
  std::string serviceName;
  std::string serverRole;
  std::string host;
  std::string port;
  Transport::type transport;
  Downstream downstream;

  _Downstream__isset __isset;

  /* blah elided blah */
};
}}}

Compilation fails with

{{{
tracetest_types.h:64:14: error: field ‘downstream’ has incomplete type 
‘jaegertracing::crossdock::thrift::Downstream’
   Downstream downstream;
              ^~~~~~~~~~

tracetest_types.h:47:7: note: definition of ‘class 
jaegertracing::crossdock::thrift::Downstream’ is not complete until the closing 
brace
 class Downstream {
       ^~~~~~~~~~
}}}

I'd argue that the {{__isset}} model is not ideal, and a {{std::expected}}-like 
"optional" or "maybe" construct would be a lot better. But presumably there are 
historical reasons for that.

The simplest correct solution would be to generate

{{{

class Downstream {
  /* ... */

  std::shared_ptr<Downstream> downstream;

  /* ... */
};

}}}

instead.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to