locked
<filesysystem> and VS 2019 16.3.0 RRS feed

  • Question

  • VS 2019 Community update 16.3.0, Win'7 Pro SP1

    Code:

    #include "stdafx.h"
    #include <filesystem>
    #include "ANNetDef.h"
    #include "Network.h"
    
    
    #pragma once
    
    //using namespace filesystem;
    using namespace experimental::filesystem;
    
     void MyFn())
      {
        assert(exists(path(strFilePathName.c_str())));
    
        ..................................;
    
    }


    Before upgrade to 16.3.0 all worked just fine. After upgrade compiler complains:

    1>ANNet.cpp

    1>C:\VS2019\Projects\ANNet\ANNet\DataProvider.h(477,5): error C2027: use of undefined type 'std::experimental::filesystem::v1::path'

    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\include\fstream(41): message : see declaration of 'std::experimental::filesystem::v1::path'

    1>ANNPropSheet.cpp

    1>C:\VS2019\Projects\ANNet\ANNet\DataProvider.h(477,5): error C3861: 'exists': identifier not found

    and the same for all <filesystem> types and functions.

    #include "stdafx.h"
    #include <filesystem>
    #include "ANNetDef.h"
    #include "Network.h"
    
    
    #pragma once
    
    using namespace filesystem
    
    ............................................
    
        assert(exists(path(strFilePathName.c_str())));
    
    ...............................................
    

    gives a complaint 'path': ambiguous symbol."

    "using namespace experimental::filesystem::v1' does not help either.

    Any help ?(It is urgent.)

    Wednesday, September 25, 2019 1:13 AM

Answers

  • Thanks for reply.

    No, it is not the most important.

    First, namespace for path and exists and other filesystem items in VC++ of VS 2019 is still experimental::filesystem. Compiler says the 'path' class is in experimental::filesystem::v1. And, indeed, I see it in the header the compiler sends me to. So I do not understand why using namespace filesystem is accepted.

    Second, in up to update 16.2.0 the compiler was very happy. It started its complaints only after update 16.3.0.

    • Marked as answer by Geoyar Wednesday, September 25, 2019 5:36 PM
    Wednesday, September 25, 2019 2:23 PM

All replies

  • Well, most importantly:

    gives a complaint 'path': ambiguous symbol."

    This is an issue on your part. The recommendation is to never use using namespace in a header because it pulls everything into the global scope not only in the header, but in the source file that the header is included in and all headers after this one. This means that accessing the unqualified name may result in the compiler not knowing what name you mean.

    An example on how you can get this error:

    namespace a
    {
    	struct t
    	{
    	};
    }
    
    namespace b
    {
    	struct t
    	{
    	};
    }
    
    using namespace a;
    using namespace b;
    
    int wmain()
    {
    	t my_t;
    
    	return 0;
    }

    This produces the output:

    1>C:\Users\Darran\source\repos\meh\meh\main.cpp(20,4): error C2872: 't': ambiguous symbol
    1>C:\Users\Darran\source\repos\meh\meh\main.cpp(3,9): message : could be 'a::t'
    1>C:\Users\Darran\source\repos\meh\meh\main.cpp(10,9): message : or       'b::t'

    Notice one very important thing that you didn't provide, it tells you the types that the name could refer to. What's more, it should tell you the file and the line that the type was defined in too.

    The thing that you should do is remove using namespace std and using namespace filesystem from your header files and in the headers refer to the types by using the fully qualified name. For example:

    assert(std::filesystem::exists(std::filesystem::path(strFilePathName.c_str())));

    Since you are providing the full type name, the compiler should have no issues knowing which type to use.


    This is a signature. Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.


    • Edited by Darran Rowe Wednesday, September 25, 2019 2:35 AM
    • Proposed as answer by Guido Franzke Wednesday, September 25, 2019 7:29 AM
    Wednesday, September 25, 2019 2:34 AM
  • Thanks for reply.

    No, it is not the most important.

    First, namespace for path and exists and other filesystem items in VC++ of VS 2019 is still experimental::filesystem. Compiler says the 'path' class is in experimental::filesystem::v1. And, indeed, I see it in the header the compiler sends me to. So I do not understand why using namespace filesystem is accepted.

    Second, in up to update 16.2.0 the compiler was very happy. It started its complaints only after update 16.3.0.

    • Marked as answer by Geoyar Wednesday, September 25, 2019 5:36 PM
    Wednesday, September 25, 2019 2:23 PM
  • Corrections:

    I have copied example of using filesystem (old one) from Microsoft:

    // FSys.cpp : This file contains the 'main' function. Program execution begins and ends there.
    //
    
    // filesystem_path_example.cpp
    // compile by using: /EHsc
    #include <string>
    #include <iostream>
    #include <sstream>
    #include <filesystem>
    
    using namespace std;
    using namespace filesystem;
    
    wstring DisplayPathInfo()
    {
      // This path may or may not refer to an existing file. We are
      // examining this path string, not file system objects.
      path pathToDisplay(L"C:/FileSystemTest/SubDir3/SubDirLevel2/File2.txt ");
    
      bool bEx = exists(pathToDisplay);
    
      wostringstream wos;
      int i = 0;
      wos << L"Displaying path info for: " << pathToDisplay << endl;
      for (path::iterator itr = pathToDisplay.begin(); itr != pathToDisplay.end(); ++itr)
      {
        wos << L"path part: " << i++ << L" = " << *itr << endl;
      }
    
      wos << L"root_name() = " << pathToDisplay.root_name() << endl
        << L"root_path() = " << pathToDisplay.root_path() << endl
        << L"relative_path() = " << pathToDisplay.relative_path() << endl
        << L"parent_path() = " << pathToDisplay.parent_path() << endl
        << L"filename() = " << pathToDisplay.filename() << endl
        << L"stem() = " << pathToDisplay.stem() << endl
        << L"extension() = " << pathToDisplay.extension() << endl;
    
      return wos.str();
    }
    
    int main(int argc, char* argv[])
    {
      wcout << DisplayPathInfo() << endl;
      // wcout << ComparePaths() << endl; // see following example
      wcout << endl << L"Press Enter to exit" << endl;
      wstring input;
      getline(wcin, input);
      return 0;
    }
    
    I added only function 'exists.'

    The example was old, so it had

    #include "experimental/filesystem"
    
    using namespace std::experimental::filesystem

    and did not compile. Change to

    #include "filesystem"
    
    using namespace filesystem

    makes it work just fine. I have changed only '#include...' and 'using namespace....'

    Did MS abandoned 'experimental' in filesystem?

    Wednesday, September 25, 2019 3:13 PM
  • >Did MS abandoned 'experimental' in filesystem?

    It's no longer experimental :)
    https://devblogs.microsoft.com/cppblog/announcing-msvc-conforms-to-the-c-standard/

    • Proposed as answer by Guido Franzke Thursday, September 26, 2019 6:24 AM
    Wednesday, September 25, 2019 5:41 PM
  • It is the most important since getting your code to compile with #include <filesystem> is the most important thing.

    It becomes obvious if you actually look in the older version of the filesystem header as to why it no longer works. The first 6 lines of the 16.2 filesystem are:

    // filesystem standard header
    #pragma once
    #ifndef _FILESYSTEM_
    #define _FILESYSTEM_
    #ifndef RC_INVOKED
    #include <experimental/filesystem>
    

    yes, it includes the experimental/filesystem header.

    If you look at the first 6 lines of the 16.3 filesystem header:

    // filesystem standard header
    #pragma once
    #ifndef _FILESYSTEM_
    #define _FILESYSTEM_
    #include <yvals_core.h>
    #if _STL_COMPILER_PREPROCESSOR

    notice how it no longer includes experimental/filesystem?

    The experimental/filesystem header is the old version of the header before it was written to conform with the C++17 standard. Microsoft became more agressive with 16.3 in removing the experimental version because they are non conformant. But they couldn't just outright remove the header.

    What they did was to remove the automatic inclusion of experimental/filesystem from the 16.3 filesystem header and actually added:

    #ifndef _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
    #error The <experimental/filesystem> header providing std::experimental::filesystem is deprecated by Microsoft \
    and will be REMOVED. It is superseded by the C++17 <filesystem> header providing std::filesystem. \
    You can define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING to acknowledge that you have received this warning.
    #endif // _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING

    to the top of the 16.3 experimental/filesystem header.

    So this header and the std::experimental::filesystem is slated for removal, this means you want to use std::filesystem.


    This is a signature. Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    • Proposed as answer by Guido Franzke Thursday, September 26, 2019 6:25 AM
    Thursday, September 26, 2019 5:55 AM
  • Hi,

    I am on VS 2019 and have tried everything to get std::filesystem working... I #include <filesystem>
    I even make sure I am on c++17 and latest. however it still just says that filesystem does not exist in std :/
    Wednesday, July 29, 2020 4:54 AM
  • Hi,

    I am on VS 2019 and have tried everything to get std::filesystem working... I #include <filesystem>
    I even make sure I am on c++17 and latest. however it still just says that filesystem does not exist in std :/

    Hello Ezerox,

    please ask a new question in the forum, not here (this post is closed already), because I don't see what your question has to do with the experimental filesystem. In your new question you should provide source code how you define your variable and what exact compiler error you get.

    Regards, Guido


    Wednesday, July 29, 2020 6:00 AM
  • It is also useful to give the exact version of Visual Studio you are using. For example the latest release version is Visual Studio 2019 16.6.5 and the current preview is Visual Studio 2019 16.7 preview 6. This gives a lot of information, like whether or not std::filesystem actually exists.


    This is a signature. Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    Wednesday, July 29, 2020 8:41 AM