Somthing of bad understanding in "SetCurrentDirectory" ("windows.h") in CPP

I don't know what's happened here. Here is the code sample:

#include<stdio.h>
#include<iostream>
#include<string>
#include <Windows.h>
using namespace std;
int main()
{
    char my_current_path[1024];
    string current_path(R"(C:)");
    if (!SetCurrentDirectory(current_path.c_str()))
        cout << "cant change to that directory.";
    GetCurrentDirectory(1024, my_current_path);
    std::cout << my_current_path << endl;
    system("pause");
    return 1;
}

What I'm doing here is trying to change the directory to some directories.

There is two strange things with my code.

(1 Strange thing)

When I try to change to "c:" like that:

#include<stdio.h>
#include<iostream>
#include<string>
#include <Windows.h>
using namespace std;
int main()
{
    char my_current_path[1024];
    string current_path(R"(C:)");
    if (!SetCurrentDirectory(current_path.c_str()))
        cout << "cant change to that directory.";
    GetCurrentDirectory(1024, my_current_path);
    std::cout << my_current_path << endl;
    system("pause");
    return 1;
}

It's not working and not changing the path (and its the good thing.) but its not show me the message that shown when the directory isn't changed:

cout << "cant change to that directory.";

Why is that? (When I try to change something like "efef:" or "exist?" it is showing me that's messege. But Why here it doesn't show me, and also doest change the current working directory?

(Second Strange thing)

When I change the directory to "G:" Its for some reason working..

#include<stdio.h>
#include<iostream>
#include<string>
#include <Windows.h>
using namespace std;
int main()
{
    char my_current_path[1024];
    string current_path(R"(G:)");
    if (!SetCurrentDirectory(current_path.c_str()))
        cout << "cant change to that directory.";
    GetCurrentDirectory(1024, my_current_path);
    std::cout << my_current_path << endl;
    system("pause");
    return 1;
}

That code compiled, showing that I successfully changed the directory to "G:". After changing to that path, I'm trying to change to "C:" (Which before, didn't did anything) and now its working! but in strange way, its not moving to "C:\" But to:

C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE

And its weird that before its not worked, and now when I'm in "G:" path and trying to move to "c:" again, then its move to path that I didn't even wanted!


If you want to specify the root directory on a drive, you must include a backslash, i.e., C:\.

The syntax you are using, C:, has a different meaning. The command shell separates the concepts of the current drive and the current directory on each drive, so that you can switch between drives quickly without having to retype the full path each time. This feature was introduced (a long time ago) for backwards compatibility reasons (see below) but is actually very useful; power users will sometimes map multiple drive letters to the same drive or network share specifically in order to take advantage of this functionality.

Although only the command shell keeps track of the current directory for each drive, the Win32 API knows how to look them up, and does so whenever you specify a drive but no path. As a special case, if the drive specified is the current drive, it expands to the actual current directory rather than the saved current directory.

So in your example the incomplete path C: is expanded to the current directory for the C drive; since your current directory is already on the C drive, SetCurrentDirectory(R"(C:)") is a no-op. If you want to change to the root directory, you should use SetCurrentDirectory(R"(C:\)") instead.

In your testing, there was no saved current directory for the G: drive, and it was not the current drive, so the effect was to set the current directory to G:\, i.e., you got the behaviour you expected but not for the reason you were expecting. If you had launched the program from the command shell and a current directory had been saved for the G drive, you'd have wound up there instead.

The same thing applies to opening files; C:file.txt will open file.txt from the current directory for the C drive, whereas C:\file.txt will open file.txt from the root directory.

See Raymond Chen's blog post, Why does each drive have its own current directory? for a discussion of the history of this feature.