3 ms·
The issue entirely hits that undefined behaviour. The problem is a race condition in symlinks -- a race condition implies a change, which is concurrent access,
by CJefferson 3y ago
The issue entirely hits that undefined behaviour. The problem is a race condition in symlinks -- a race condition implies a change, which is concurrent access, and the C++ standard clearly states any change to the filesystem by another program leads to undefined behaviour.
Sure, the "concurrent access" is another program, but the standard says another program changing an object you are accessing leads to undefined behaviour -- which does make, writing basically any C++ program that does filesystem access on a modern OS with other programs running completely impossible according to the letter of the standard, so I'm really not sure why it's written in that way.
- adev_ 3y agoThe answer to that is there: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4003.html https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n40... It is mainly wording around specifying that the result of a concurrent access can not be guaranteed. Which here Rust is no different, it just does not have a specification for his stdlib (yet)
- CJefferson 3y agoI disagree, while rust doesn't have a formal specification, they would consider any crashes in safe code caused by parallel filesystem access to be unacceptable, while for years the C++ committee has been happy to say "You fool, you invoked undefined behaviour. Game over". I don't see any evidence from looking at the standard this bit of undefined behaviour is somehow "less undefined" than any other bit of undefined behaviour.
- kllrnohj 3y agoNo it isn't, it's just a bug and it was fixed, just like it was for Rust. Nobody hid behind UB for this and the time from reporting the issue to fixing it was about 2 weeks for both libcxx and libc++ https://bugs.chromium.org/p/llvm/issues/detail?id=19 https://bugs.chromium.org/p/llvm/issues/detail?id=19 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104161 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104161 Absolutely zero mention or attempted defense of "hurr durr but UB says we can do this!!!"
- SAI_Peregrinus 3y agoC++ is the standard. Not the implementations. The bug is fixed in the implementations, but remains in C++.
- kllrnohj 3y agoWhere is the bug in the C++ standard? std::remove_all states: > 1,2) The file or empty directory identified by the path p is deleted as if by the POSIX remove. Symlinks are not followed (symlink is removed, not its target). > 3,4) Deletes the contents of p (if it is a directory) and the contents of all its subdirectories, recursively, then deletes p itself as if by repeatedly applying the POSIX remove. Symlinks are not followed (symlink is removed, not its target). Nowhere in there does it say "lol but FUCK YOU if you're on a multiprocessing system lololololol" or anything remotely close to that.
- SAI_Peregrinus 3y ago> 29.11.2.3 File system race behavior [fs.race.behavior] > 1 A file system race is the condition that occurs when multiple threads, processes, or computers interleave access and modification of the same object within a file system. Behavior is undefined if calls to functions provided by subclause [fs.race.behavior] introduce a file system race. > 2 If the possibility of a file system race would make it unreliable for a program to test for a precondition before calling a function described herein, Preconditions: is not specified for the function. [ Note: As a design practice, preconditions are not specified when it is unreasonable for a program to detect them prior to calling the function. — end note ] There you go. "Behavior is undefined" is essentially "fuck you, you won't get any error you'll just get garbage at runtime". It does thankfully allow the implementations to make it an error at runtime (as they did), but does not require it, so the standard still has the bug.