title: Why does boost::filesystem::canonical() require the target path to exist?
body: <p>The documentation for <a href="http://www.boost.org/doc/libs/1_58_0/libs/filesystem/doc/reference.html#canonical" rel="noreferrer"><code>boost::filesystem::canonical(const path&amp; p)</code></a> states:</p>
  
  <blockquote>
    <p>Overview: Converts p, which must exist, to an absolute path that has no symbolic link, dot, or dot-dot elements.<br>
    ...<br>
    Remarks: !exists(p) is an error.</p>
  </blockquote>
  
  <p>The consequence of this is that if p identifies a symbolic link whose target does not exist, the function fails with <code>file not found</code> and does not return a path.</p>
  
  <p>This seems overly restrictive to me: just because the target of the link doesn't exist, I see no reason why the function can't resolve the <em>path</em> of that non-existent target.  (In comparison, <code>absolute()</code> imposes no such restriction.)</p>
  
  <p>(Clearly, if a symbolic link <em>within</em> the path is broken, the target path can't be resolved.)</p>
  
  <p>So, is there a legitimate justification for this restriction?  </p>
  
  <p>And even if there is, is there not also justification for the creation of a variant of the function that does not have this restriction?  (Without such a variant, obtaining the path requires error-prone manual replication of 99% of what <code>canonical()</code> already does.)</p>
  
  <p>I appreciate that the semantic subtleties that exist between <code>stat()</code> and <code>lstat()</code> apply equally to this case - which is precisely why I think a variant of the function is equally justified.</p>
  
  <p>NB: This question is equally applicable to the <code>std::experimental::filesystem</code> library (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4100.pdf" rel="noreferrer">n4100</a>),  which is based on <code>boost::filesystem</code>.</p>
  
  <p>EDIT:</p>
  
  <p>After @Jonathan Wakeley's very knowledgeable answer below, I'm still left with the essence of my original questions, which I'll reframe slightly:</p>
  
  <ul>
  <li><p>Is there an <em>underlying technical or logical reason</em> why <code>boost::filesystem::canonical()</code> requires the target to exist?  By that I mean, does the non-existence of the target somehow make it impossible to resolve the path to canonical form?</p></li>
  <li><p>If not, is there any technical or logical reason <em>not</em> to propose a variation of the function that differs only from the existing form in that it does <em>not</em> require the target to exist?</p></li>
  <li><p>In the transformation (as I understand to be the case) of <code>boost::filesystem</code> into the proposed N4100 <code>std::experimental::filesystem</code>, has this restriction on <code>canonical()</code> been adopted after due consideration, or is it just 'falling through' from the Boost definition?</p></li>
  </ul>
  
  <p>EDIT 2:</p>
  
  <p>I notice that Boost 1.60 now provides the function <code>weakly_canonical()</code>: "Returns p with symlinks resolved and the result normalized.  Returns: A path composed of the result of calling the <code>canonical()</code> function on a path composed of the leading elements of p that exist, if any, followed by the elements of p that do not exist, if any."</p>
  
  <p>EDIT 3:</p>
  
  <p><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0219r1.html" rel="noreferrer">More discussion of this</a> in relation to <code>std::filesystem</code>.</p>