【问题标题】:why can I assign a string literals to a char* pointer [duplicate]为什么我可以将字符串文字分配给 char* 指针 [重复]
【发布时间】:2013-04-12 11:27:54
【问题描述】:

我认为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;

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

【问题讨论】:

  • @unkulunkulu 答案在 C++ 中有点不同:根据 [lex.string],它是 C++ 中的 const char 数组
  • @DyP,链接问题的答案涵盖 C++
  • @unkulunkulu 哦,对不起,你是对的。尽管如此,上面的代码在 C++ 中是 invalid 的,请参阅 [diff.lex]
  • @DyP,抱歉我的无知,但是 [diff.lex] 是什么:D
  • @DyP - VC2010 不太可能完全遵循 C++11 标准。 :-) 该部分是语言修订的一部分,并且更早允许转换(因为 C 没有 const 的时候)。

标签: c++ visual-c++


【解决方案1】:

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

警告:不推荐将字符串常量转换为 'char*' [-Wwrite-strings]

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

char *str2 = "this is good";

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

【讨论】:

    【解决方案2】:

    字符串字面量确实是常量。但是,数组衰减为指针,您将非const 指针指向数组中的第一个元素:

    char *str2 = "this is good";
    

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

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

    【讨论】:

    • [diff.lex] 明确指出 char* p = "abc"; 在 C++ 中无效。现在我很困惑。
    • @Dyp 在vc++中有效,但是不能修改值。
    • 那么 msvc 将文字作为 char*,对吗?
    • @zoujyjs 看我的回答。
    • 我刚刚陷入了这样一个事实,即 MSVS 2013 不会将其报告为错误,无论是 /W4 还是 /Wall 还是 /Wall/W4 — 猪!我不确定/W4/Wall 之间有什么区别:两者都被描述为最大。
    【解决方案3】:

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

    [conv.array]

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

    实际上,任何窄字符串文字都是“n const char 数组”类型,但正如您在上面看到的,有一个(在 C++03 中已弃用)功能可以将它们隐式转换为 char * 类型的右值.

    你仍然不能改变字符串的内容,就像你做了一个const_cast:指针指向的对象已经被声明为const,因此不允许修改(未定义的行为)。

    【讨论】:

    • 不错!所以,它仍然是 const char* 但有一个隐式转换。明白了!
    • @zoujyjs 差不多。有两种转换。 [conv.array],括号中的文本来自我:“abc”被转换为[从4个const char的数组]到“pointer to const char”作为数组到指针的转换,然后到“pointer to char”作为资格转换。
    猜你喜欢
    • 2011-10-11
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    • 1970-01-01
    • 2017-01-18
    • 1970-01-01
    相关资源
    最近更新 更多