警告:从字符串文字转换为' char *'已弃用

时间:2016-04-13 10:25:27

标签: c++ string

在下面的(C ++)代码中,

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);

我有以下编译警告:

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";

我看到char指针是不安全的,但是我不确定在这种情况下是否会出现问题,而type在任何其他地方都没有使用。

我确实知道像*type = 'X';这样做的可能性会很糟糕,因为它会改变字符串文字,并可能导致我的机器崩溃。

问题:

char指针有什么问题?

const char * type = new char[20];是摆脱警告的好方法吗?

2 个答案:

答案 0 :(得分:6)

string literal的类型为const char[],请注意:

  

在C中,字符串文字的类型为char [],可以直接分配给(非const)char *。 C ++ 03也允许它(但不赞成它,因为文字在C ++中是const)。没有强制转换,C ++ 11不再允许这样的赋值。

然后

  

1. char指针出了什么问题?

如你所说,char *可以改变字符串文字并导致UB。

您可以创建一个从字符串文字初始化的数组,然后稍后修改数组,例如:

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

2.Is const char * type = new char [20];摆脱警告的好方法?

这里不需要创建新数组,因为您只是更改指针本身的值,而不是它指向的内容。您只需将type的类型更改为const char*

即可
const char * type = "";

答案 1 :(得分:2)

变化:

char * type = "";

为:

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

这是因为:""(同样适用于其他文字)是一个字符串文字,它是数组类型。在这种情况下,它是const char[1]

要检查它,您可以使用编译器错误技巧:

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

输出:

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

其中const char [1]""的类型,其大小为1,因为它只保留空字符:&#39; \ 0&#39;。

您可以将其分配并用作const char*,因为数组会衰减指向其第一个元素。