3

Given the following code:

  fs::path p{ "a/b/" };
  fs::path q{ "a/b/." };  
  assert(p == q);         

[Note the extra dot at the end of the string defining q.]

With the above, boost::filesystem accepts p == q as true, but gcc's and llvm's implementation of std::filesystem say it is false.

Why the discrepancy between boost and std?

P.S. In previous versions of this question, I erroneously thought that the paths were supposed to be normalized before comparison. That is not the case. Even so, the discrepancy between boost and std is still a mystery to me.

Curious
  • 128
  • 5
  • 3
    Why would you expect those to compare equal? – T.C. Apr 13 '20 at 16:47
  • Dot does refer to itself, so why not? – Zuodian Hu Apr 13 '20 at 17:41
  • 1
    much better imho. Maybe I should tell you that while I am interested in anything, I cannot help on anything. Though to know if I can I first try to understand the question. Sorry if I raised false expectations, but if you can agree that it was an improvment then of course it wasn't for me but for you to increase chances of getting an answer – 463035818_is_not_an_ai Apr 14 '20 at 13:10
  • "The way I understand it, the comparison should be done after the paths are normalized." Why? I would say that `"a/b/"` and `"a/b/."` are different paths that name the same entry – Caleth Apr 14 '20 at 15:56
  • 1
    @ Caleth: a) The first reason, as I mentioned in the question, is that "a/.././b", and "a///..//.////b" compare equal. They are different paths that name the same entry, to use your language, but they compare equal. That implies that some sort of normalization is going on. b) Importantly, Boost disagrees with you. – Curious Apr 18 '20 at 15:05

1 Answers1

1

The short answer is that . on Unix is an actual filesystem node link, and that matters sometimes. See this stack overflow answer.

EDIT

However, I can't presume to know the Standard Committee's intentions with regard to filesystem library behavior, nor do I think it's reasonable for the library to know that much about Unix symlink behavior. In short, this may or may not just be a quirk of the Standard wording vs Boost's opinion of how things should work.

Zuodian Hu
  • 979
  • 4
  • 9
  • Path comparisons are performed without accessing the filesystem, as far as I can tell. I'm afraid it's deeper than that. – Curious Apr 14 '20 at 20:22
  • @Curious: "*Path comparisons are performed without accessing the filesystem*" But path comparisons have to be defined in such a way that, if two paths are equal, they should definitely name the same entity in the filesystem. If `.` could be considered a different entity in some cases, then logical path equality testing must recognize that. – Nicol Bolas Apr 14 '20 at 22:14
  • @Nicol Bolas: Correct. That's why the standard has rules for "normalizing" a path. In the standard, for example, you can refer to: 29.11.7.1 Generic pathname format [fs.path.generic], and in particular sub-section 6: Normalization of a generic format pathname. Again, please refer to my full post, and my reply to Caleth, above. Particularly, my last point: boost provides a different answer. – Curious Apr 14 '20 at 22:34