0

I have a problem here. This function:

BOOL WINAPI SFileGetFileName(HANDLE hFile, char * szFileName) {
    TMPQFile * hf = (TMPQFile *)hFile;  // MPQ File handle
    char *szExt = "xxx";                // Default extension
    DWORD dwFirstBytes[2];              // The first 4 bytes of the file
    DWORD dwFilePos;                    // Saved file position

    int nError = ERROR_SUCCESS;
    int i;

    // Pre-zero the output buffer
    if(szFileName != NULL)
        *szFileName = 0;

    // Check valid parameters
    if(nError == ERROR_SUCCESS)
    {
        if(hf == NULL || szFileName == NULL)

            nError = ERROR_INVALID_PARAMETER;

    }



    // If the file name is already filled, return it.

    if(nError == ERROR_SUCCESS && *hf->szFileName != 0)

    {

        if(szFileName != hf->szFileName)

            strcpy(szFileName, hf->szFileName);

        return TRUE;

    }



    if(nError == ERROR_SUCCESS)

    {

        if(hf->dwBlockIndex == (DWORD)-1)

            nError = ERROR_CAN_NOT_COMPLETE;

    }



    // Read the first 8 bytes from the file

    if(nError == ERROR_SUCCESS)

    {

        dwFirstBytes[0] = dwFirstBytes[1] = 0;

        dwFilePos = SFileSetFilePointer(hf, 0, NULL, FILE_CURRENT);   

        SFileReadFile(hFile, &dwFirstBytes, sizeof(dwFirstBytes), NULL);

        BSWAP_ARRAY32_UNSIGNED(dwFirstBytes, sizeof(dwFirstBytes) / sizeof(DWORD));

        SFileSetFilePointer(hf, dwFilePos, NULL, FILE_BEGIN);

    }



    if(nError == ERROR_SUCCESS)

    {

        if((dwFirstBytes[0] & 0x0000FFFF) == ID_EXE)

            szExt = "exe";

        else if(dwFirstBytes[0] == 0x00000006 && dwFirstBytes[1] == 0x00000001)

            szExt = "dc6";

        else

        {

            for(i = 0; id2ext[i].szExt != NULL; i++)

            {

                if(id2ext[i].dwID == dwFirstBytes[0])

                {

                    szExt = id2ext[i].szExt;

                    break;

                }

            }

        }



        // Create the file name

        sprintf(hf->szFileName, "File%08lu.%s", hf->dwBlockIndex, szExt);

        if(szFileName != hf->szFileName)

            strcpy(szFileName, hf->szFileName);

    }

    return (nError == ERROR_SUCCESS);

}

Gives me these errors on 'make':

SFileReadFile.cpp: In function ‘bool SFileGetFileName(HANDLE, char*)’:
SFileReadFile.cpp:655:19: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
 char *szExt = "xxx";                // Default extension
               ^
SFileReadFile.cpp:700:19: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
         szExt = "exe";
               ^
SFileReadFile.cpp:702:19: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
         szExt = "dc6";
               ^
SFileReadFile.cpp:716:72: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 3 has type ‘DWORD {aka unsigned int}’ [-Wformat=]
     sprintf(hf->szFileName, "File%08lu.%s", hf->dwBlockIndex, szExt);

Please give me tips, how to fix these?

I have tried much in C++ documentation, but I had no much luck in finding what is needed. Look, I cannot do a const char const* in declaration of szext because I get many errors about constants. But I really want to get rid of these errors.

Please give me some advices or deeper explanation on why it's happening.

Niall
  • 30,036
  • 10
  • 99
  • 142
Duosora
  • 83
  • 1
  • 1
  • 8
  • 4
    Does `char const *szExt = "xxx";` work? (Note the additional `const`). A string array `"xx"` is a `char const[]` and the conversion to `char*` was deprecated circa C++14. Using `char const*` should be preferred. – Niall Nov 03 '14 at 09:24
  • You're right that `szExt` should not be defined as `const char *const szExt`, but what suggestion did you find that made you think to try that? Knowing your understanding will allow for far more useful answers. –  Nov 03 '14 at 09:24
  • @Niall Yes, that's right, but unfortunately with most questions like these, merely giving the correct answer does nothing to help anyone actually understand what's going on. (Maybe it's different here.) –  Nov 03 '14 at 09:26
  • @hvd, http://stackoverflow.com/questions/1524356/c-deprecated-conversion-from-string-constant-to-char look Howard Lovatt answer please. There was a const char const* – Duosora Nov 03 '14 at 09:27
  • @Niall, yeah, this works! Can you explain why char const* actually worked? That'll help me to not repeat the question. This got rid of szExt related errors but it still throws me %lu format error. – Duosora Nov 03 '14 at 09:29
  • @Duosora Yes, in that answer `temp` is only initialised and never re-assigned, so in that answer, the second `const` makes sense. In your code, you do re-assign `szExt`, so the second `const` does not make sense, but the first still does. –  Nov 03 '14 at 09:29
  • `char* szExt = "xxx";` allows you to overwrite your string literal `"xxx"` which may be stored in read-only memory causing a crash. In fact it doesn't make sense to be able to over-write a string literal so `const char* szExt = "xxx"; is correct. – Galik Nov 03 '14 at 09:32
  • @Duosora. It relates to the C++14 (possibly 11) deprecation of the conversion from `char const[]` to `char*` (IIRC was originally a compatibility issue with C). On the placement of the `const`, I've heard people say it's best read right to left, so `char const*` is a pointer to a constant character (array). If you wish it to be a `const` pointer, then `char const* const` which is a constant pointer to a constant character array. – Niall Nov 03 '14 at 09:32
  • I don't understand your indention & why you put so much empty lines. – GingerPlusPlus Nov 03 '14 at 09:37
  • 1
    @Niall That conversion was actually deprecated before C++11, and removed entirely in C++11. –  Nov 03 '14 at 09:39
  • @hvd. Thanks. I wasn't exactly sure on all the timelines and when it happened. – Niall Nov 03 '14 at 09:44

2 Answers2

0

These are not the errors you are getting the warning messages, and your program will work correctly.

In c++11 the initializing string the way you are using are depricated.

See other answers or you can use std::string str="xxx";

but you need to include header

smali
  • 4,687
  • 7
  • 38
  • 60
0

String literals in C++ have type of const character arrays. So you have to use a pointer to a const char if you ar going to assign a string literal to a character pointer.

So it would be more correctly to write

const char *szExt = "xxx";

Or you could use a character array instead of the pointer if you do not want to use qualifier const

char szExt[] = "xxx";

Take into account that any attempt to modify a string literal results in undefined behaviour.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335