Per M.
Per M.

Reputation: 95

warning: conversion from string literal to 'char *' is deprecated

On the (C++) code below,

char * type = "";
switch (mix_mode) {
        case GO_HISTORY_VIDEO_MIX_VISUAL_GAS:
                type = "visual gas";
                break;
        case GO_HISTORY_VIDEO_MIX_VISUAL:
                type = "visual";
                break;
        case GO_HISTORY_VIDEO_MIX_GAS:
                type = "gas";
                break;
        case GO_HISTORY_VIDEO_MIX_LARGE_IR_DIRECT:
                type = "ir direct";
                break;
        case GO_HISTORY_VIDEO_MIX_LARGE_IR_FILTERED:
                type = "ir filtered";
                break;
}
strcpy(suffix, "avi");


snprintf(filename, sizeof(filename), "%s - (%s %s).%s", name_comp, type, uid, suffix);

I have the following compilation warnings:

GO_C_MSDExportManager.cpp:192:31: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
                char * type = "";
                              ^
GO_C_MSDExportManager.cpp:195:12: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
                                type = "visual gas";
                                       ^
GO_C_MSDExportManager.cpp:198:12: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
                                type = "visual";
                                       ^
GO_C_MSDExportManager.cpp:201:12: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
                                type = "gas";
                                       ^
GO_C_MSDExportManager.cpp:204:12: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
                                type = "ir direct";
                                       ^
GO_C_MSDExportManager.cpp:207:12: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
                                type = "ir filtered";

I see the char pointer is un-safe, but I'm not sure if something could go bad in this context, while type isn't used any other place.

I do have learned that the possibility to do something like *type = 'X'; would be bad as it would alter the string literal and possible crash my machine.

Questions:

What could go wrong with the char pointer?

Is const char * type = new char[20]; a good fix to get rid of the warnings?

Upvotes: 3

Views: 8027

Answers (2)

marcinj
marcinj

Reputation: 49976

Change:

char * type = "";

to:

const char * type = "";
^^^^^ -- !

This is because: "" (the same applies to other literals) is a string literal which is of array type. In this case it is const char[1].

To check it you can use compiler error trick:

template<typename T> struct TD;
int main() {
    TD<decltype("")> ff;   
}

outputs:

main.cpp:10:22: error: aggregate 'TD<const char (&)[1]> ff' has incomplete type and cannot be defined
     TD<decltype("")> ff; 

where const char [1] is the type of "", its size is 1 because it keeps only null character : '\0'.

You can assign it and use as const char* because arrays decays to pointer to its first element.

Upvotes: 2

songyuanyao
songyuanyao

Reputation: 172894

string literal 's type is const char[], and note that:

In C, string literals are of type char[], and can be assigned directly to a (non-const) char*. C++03 allowed it as well (but deprecated it, as literals are const in C++). C++11 no longer allows such assignments without a cast.

Then

1.What could go wrong with the char pointer?

As you said, char * make it possible to alter the string literal and leads to UB.

You could create an array initialized from the string literal, and then modify the array later, such as:

char type[] = "something"; // type will contain a copy of the string literal

2.Is const char * type = new char[20]; a good fix to get rid of the warnings?

No need to create a new array here, since you're only changing the value of the pointer itself, not the content it pointing to. You should just change the type of type to const char*,

const char * type = "";

Upvotes: 8

Related Questions