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)