为什么我可以将字符串文字分配给char *指针

时间:2013-04-12 11:27:54

标签: c++ visual-c++

我认为c++中的字符串文字是const char*的类型。并且您无法将const char*对象分配给non-constant char*对象。但是在Visual Studio 2010中。以下代码可以编译而不会出现错误或警告,但会产生运行时错误。

int main(void)
{      
    char *str2 = "this is good";
    str2[0] = 'T';
    cout << str2;
    getchar();
    return 0;
}

如果我们不修改字符串的值,那么读取该值就可以了:

for(char *cp = str2; *cp !=0; ++cp) {
    printf("char is %c\n", *cp);
}
getch();
return 0;

那么为什么我们可以在这里为char *分配一个const char *?

3 个答案:

答案 0 :(得分:3)

问题出在VC ++之下,但在GCC中它有一个有意义的警告:

  

警告:已弃用从字符串常量转换为&#39; char *&#39;   [-Wwrite串]

此警告意味着尽管存在const /非const差异,编译器仍将应用隐式转换。所以,这段代码没问题(在运行时没有任何修改):

char *str2 = "this is good";

但是,修改str2会产生未定义的行为。

答案 1 :(得分:1)

字符串文字确实是不变的。但是,数组会衰减为指针,并且您将非const指针指向数组中的第一个元素:

char *str2 = "this is good";

修改const char数组的任何值都会产生未定义的行为。

这不会在gcc 4.7.2下编译干净。如果你在MSVC下将警告级别提高到警告级别4,它也可能会在那里发出警告。

答案 2 :(得分:1)

让我们看看C ++ 03而不是C ++ 11:

[conv.array]

  

不是宽字符串文字的字符串文字(2.13.4)可以转换为“指针”类型的右值    炭”;

实际上,任何窄字符串文字的类型都是“n const char数组”,但正如您在上面所读到的,有一个(已经在C ++ 03中已弃用)功能将它们隐式转换为类型{{1的rvalues }}

仍然不允许更改字符串的内容,就像你做了char *一样:指针所指向的对象已被声明为const,因此不允许修改(未定义的行为)