<div style="font-family: arial, helvetica, sans-serif"><font size="2"><div class="gmail_quote">On Tue, Jun 19, 2012 at 11:18 AM, Jeffrey Yasskin <span dir="ltr"><<a href="mailto:jyasskin@google.com" target="_blank">jyasskin@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><p>On Jun 18, 2012 1:24 PM, "Nick Kledzik" <<a href="mailto:kledzik@apple.com" target="_blank">kledzik@apple.com</a>> wrote:<br>

><br>
> On Jun 16, 2012, at 3:51 PM, Chris Lattner wrote:<br>
> > On Jun 15, 2012, at 3:48 PM, Nick Kledzik wrote:<br>
> ><br>
> >> In lld we have a Reader class which is a factory that takes .o file(s) and produces an in memory lld::File object(s).  But in doing so, there could be I/O errors (file not readable) or file may be malformed.  We are also using C++11 in lld, so we use std::unique_ptr for managing object ownership.<br>


> >><br>
> >> The Reader class currently has an interface that can be simplified down to:<br>
> >><br>
> >>   virtual error_code readFile(StringRef path, std::unique_ptr<lld::File> &result);<br>
> >><br>
> >> But this interface has become awkward to use. There are two "return" values.  This method is a unique_ptr "source" but the use of a by-refernce parameter means you have to start with an uninitialized unique_ptr and the readFile() has to std::move() into it.   unique_ptr is much nicer to use as a return value.<br>


> ><br>
> > Not a c++'11 expert here, but does a returning an std::tuple work?<br>
> I talked to Howard about that.  It does work, but it is cumbersome.  Either:<br>
><br>
> std::tuple<std::unique_ptr<lld::File>, error_code>  result = reader.readFile(path);<br>
></p>
</div><p>I suggest an error_or<T> class that can be combined with any result type, not just File. It could be implemented with a fully generic variant class, but the interface would likely be better with some specialization to errors.</p>
</blockquote><div>I also really like the variant design. It has a few important advantages IMO:</div><div><br></div><div>1) No pointers or heap allocations. These make code more bug prone and can needlessly hurt optimizers. (although the latter is hopefully not relevant in this specific case)</div>
<div><br></div><div>2) No "error" state in the file object. Either you have a fully constructed object or you don't.</div><div><br></div><div>3) An explicit API to check and instrument whether an error has occured. For example, it is harder to "forget" to check the error, and carry on manipulating the file. The implementation can assert in debug builds to catch this early, etc.</div>
<div><br></div><div>4) Doesn't require polymorphic types (but they can be supported if needed). Essentially, you can wrap a *specific* file type, rather than being forced to use some generic file type.</div><div><br></div>
<div><br></div><div>One interesting possibility is that you can grow the same pattern to different levels of complexity as needed (and thus keep it as simple as possible as long as possible):</div><div><br></div><div>error_or<T>  -- wraps the existing error_code with a nice interface</div>
<div>linker_error_or<T> -- wraps both an error_code and some linker specific error handling logic</div><div>file_error_or<T> -- provides completely custom error information specific to file-loading-errors.</div>
<div><br></div><div><br></div><div>I'm not saying which (if any) of these would be appropriate, just pointing out that this pattern can be followed to greater and lesser degrees of specificity.</div></div></font></div>