I'm working on a file traversal project, and I want to keep track of the current item that's being examined, so I have an external filesystem::path CurrentItem value that I change on each level/step of traversal to keep up to date.
I'm using a recursive function that takes a const filesystem::path& to traverse through the files, the const path reference rather than a path itself so I can avoid the string copy overheads. I know in the scale of things, it's probably not the most heavy of operations in this program, but it's what I chose to do.
When traversing beyond the entry-depth of the loop, when I update the CurrentItem path with the loop's directory_entry's path, the function parameter path also somehow gets set. It's baffling to me especially considering that adding a watch it showed me that even the underlying wstring is marked as const, so I'm at a loss.
Bottom line, I want to know if I somehow did something wrong enough to break const, or if it's actually a bug that I just need to work around. I can just create a secondary path that I assign the input value to, and that doesn't have the same problem as the const parameter, or I can change the parameter to a plain const path, but both of these solutions reintroduce the additional unnecessary copies that I wanted to avoid.
I separated the code from my project in a completely clean environment, and it exhibits the same exact behavior.
I reproduced all external variables as they would be, minus class encapsulation. I'm running in VS19 on windows 10, tested on both 32 and 64 bit and the same happens. Here it is:
#include <iostream> #include <filesystem> using namespace std::filesystem; std::error_code ec; path StartDirectory = L"D:/Camera Import/Animals/RAW"; path CurrentItem; bool Recursive = true; bool DoFiles = false; bool DoFolders = true; void HandleFilesInDirectory(const path& thisPath); int main() { std::cout << "Hello World!\n"; StartDirectory.make_preferred(); CurrentItem = StartDirectory; if (is_directory(StartDirectory, ec)) { HandleFilesInDirectory(StartDirectory); } } void HandleFilesInDirectory(const path& thisPath) { for (const directory_entry& entry : directory_iterator(thisPath)) { auto type = entry.status().type(); // This assignment operation causes the const path& thisPath to be reassigned somehow, // despite it being const and also being unrelated to the items in the assignment CurrentItem = entry.path(); if (entry.is_directory(ec)) { if (Recursive) { HandleFilesInDirectory(CurrentItem); } if (DoFolders) { // Do project-specific operations } } else if (DoFiles && entry.is_regular_file(ec)) { // Do project-specific operations } } CurrentItem = thisPath; if (!thisPath.compare(StartDirectory)) { // Do project-specific operations } }
constreference applies to the variable, not the object.