Reputation: 95
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
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
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