Home > Enterprise >  Compiler insists rename() function is of type void
Compiler insists rename() function is of type void

Time:02-08

everyone! I'm trying to write a program capable of renaming files, but I'm encountering a weird issue. When I write this:

string oldname, newname;
rename(oldname, newname);

Everything works fine. The file is renamed and there are no problems. But then when I go ahead and try this:

int result;
result = rename(oldname, newname);
if(result)
//stuff
else
//other stuff

The "=" gets a fresh new red underline and I get an error "a value of type "void" cannot be assigned to an entity of type "int"". I also tried

if(rename(oldname, newname))
//stuff

Then I just get "expression must have bool type (or be convertible to bool)"

Microsoft's documentation says that the rename function returns 0 if successful and nonzero if not successful. After a lot of googling I found countless examples of code that use the second or third snippet without issue, and none of it has helped me understand what might be different in my situation. The language standard is C 17. I can't think of any other relevant details, but just in case, here is a snippet of the actual code with all the "includes":

#include <windows.h>
#include <stdlib.h>
#include <tchar.h>
#include <vector>
#include <string>
#include <filesystem>
#include <fstream>
#include <time.h>
#include <iostream>
#include <codecvt>
#include <locale>
#include <sstream>
#include <windowsx.h>
#include <Shlobj.h>

using namespace std;
using namespace std::filesystem;

tmp_wstr = oldname   L"\n\nwill be renamed to:\n\n"   newname   L"\n\nWould you like to proceed?";
                        msgboxID = MessageBox(NULL, tmp_wstr.c_str(), L"Renaming...", MB_YESNO | MB_SYSTEMMODAL);
                        switch (msgboxID)
                        {
                        case IDYES:
                            result = rename(oldname, newname);
                            if (result)
                            {
                                error = true;
                                msgboxID = MessageBox(NULL, L"Unable to rename", NULL, MB_OK | MB_SYSTEMMODAL);
                            }
                            else
                                error = false;
                            break;
                        case IDNO:
                            error = true;
                            break;
                        }

Here oldname and newname are wstring instead of string, but I have tried using string and the error persists.

CodePudding user response:

You are expecting to call the C standard library function rename() with signature:

int rename(const char*, const char*);

But that function would not be a viable overload for rename(oldname, newname) if oldname and newname are of type std::(w)string, since std::(w)string is not implicitly convertible to const char*.

So, you must be calling a different function named rename(). Since you used:

using namespace std::filesystem;

you are, in fact, calling the following overload of the C standard library function std::filesystem::rename() with signature:

void rename(const std::filesystem::path&, const std::filesystem::path&);

which is viable with your arguments, since std::filesystem::path is constructible from std::(w)string.

This function has a void return type, explaining the error messages. As explained in the link, it doesn't return a status code, but instead throws an exception if there is an error.

  •  Tags:  
  • Related