1

NOTE: this does not fail to #include <filesystem>. It fails afterward.

I’m on a macOS 10.15, using clang 11. Output of clang --version:

Apple clang version 11.0.0 (clang-1100.0.33.17)
Target: x86_64-apple-darwin19.4.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

When I try to compile something simple like:

#include <filesystem>

using namespace std;

filesystem::path dev_dir;

int main() {
    dev_dir = "/dev/";
    return 0;
}

The compiler does find the filesystem library, but doesn’t recognize the namespace:

$clang trigger_controller.cpp -o trigger_controller

trigger_controller.cpp:##:##: error: use of undeclared identifier 'filesystem'
filesystem::path dev_dir;

This is the file I believe I’m trying to include (which I’ve confirmed exists):

// /usr/local/include/c++/9.2.0/filesystem

#ifndef _GLIBCXX_FILESYSTEM
#define _GLIBCXX_FILESYSTEM 1

#pragma GCC system_header

#if __cplusplus >= 201703L

#include <bits/fs_fwd.h>
#include <bits/fs_path.h>
#include <bits/fs_dir.h>
#include <bits/fs_ops.h>

#define __cpp_lib_filesystem 201703

#endif // C++17

#endif // _GLIBCXX_FILESYSTEM

What am I doing wrong? Are there specific compiler options I need? Is the namespace wrong?

crashmstr
  • 28,043
  • 9
  • 61
  • 79
owengall
  • 455
  • 4
  • 11
  • 3
    The entire contents of this header are wrapped in `#if __cplusplus >= 201703L`, so try again with `-std=gnu++17`. (They really should have put an `#else #error "This header requires C++17"` in there.) – zwol Jun 16 '20 at 14:34
  • 1
    (Note: the hyperconformant modes, `-std=c++XX`, can break the system headers, so I recommend not using them unless you're prepared to deal with that.) – zwol Jun 16 '20 at 14:36
  • @zwol That was it, thank you! By the way, I had to switch to `clang++` because then there were other errors. – owengall Jun 16 '20 at 14:45

1 Answers1

1

Yes, there are specific compiler options you need. Notice that the entire contents of this header, apart from boilerplate, are wrapped in an #if __cplusplus >= 201703L ... #endif block. That means the header is effectively empty unless the compiler declares conformance with the 2017 revision of the C++ standard (or later).

For clang and gcc, standards conformance level is controlled with the command line option -std. GCC's documentation for this option is here; I don't know where to find clang's documentation, but clang generally tries to be command-line compatible with gcc, so the same options should work.

In this case, the exact option you should use is -std=gnu++17 for C++ 2017. As of this writing, support for newer revisions of the C++ standard is still "experimental" and "will almost certainly change in incompatible ways", so I would avoid it. I also recommend you avoid the hyperconformant variant of this mode, -std=c++17, because it has a good chance of exposing bugs in MacOS system headers.

zwol
  • 135,547
  • 38
  • 252
  • 361