Home > Net >  different behaviour for filesystem::path(filePath).filename() between gcc7.3 and gcc9.3
different behaviour for filesystem::path(filePath).filename() between gcc7.3 and gcc9.3

Time:07-05

I see different outputs when running this piece of code in gcc7.3 (using C 14) and gcc9.3 (using C 17):

#include <iostream>
#if (__cplusplus >= 201703L)
    #include <filesystem>
    namespace fs = std::filesystem;
#else
    #include <experimental/filesystem>
    namespace fs = std::experimental::filesystem;
#endif
using namespace std;
std::string getBaseName(const std::string& filePath) {
    return fs::path(filePath).filename().string();
}
int main()
{
    std::cout<<"getBaseName(/test/absolute/dir/)="<<getBaseName("/test/absolute/dir/")<<std::endl;
    std::cout<<"getBaseName(/)="<<getBaseName("/")<<std::endl;
    return 0;
}

In gcc7.3 (C 14), it gave me:

getBaseName(/test/absolute/dir/)=.
getBaseName(/)=/

In gcc9.3(C 17), I got:

getBaseName(/test/absolute/dir/)=
getBaseName(/)=

I wonder if this is a bug in gcc7.3 (and therefore std::experimental) and if so, do we have any workaround without relying on any third party libraries?

CodePudding user response:

<experimental/filesystem> implements the filesystem library according to the Filesystem TS (basically an experimental extension of C 14), while <filesystem> is the filesystem library part of C 17 (and later).

The two are not identical specifications. The latter is based on the experience with the former, but as the former was never part of the standard proper, changes to the API could be made for C 17.

This is one of these changes. Specifically, the change is the resolution of NB comments on the C 17 draft. See https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0492r2.html#US74.


For workaround, there isn't one really. No C compiler is required to support <experimental/filesystem> at all and <filesystem> will be available only starting with C 17.

If you really need support for C 14 or earlier, maybe you should use <boost/filesystem> instead for portability. However, I think the interface may differ slightly from both C 17 std::filesystem and the Filesystem TS.

Otherwise I would recommended just requiring C 17 and dropping any support for <experimental/filesystem>.

  • Related