“hello world”字符串文字可以分配给char *类型吗?

时间:2012-11-06 09:48:35

标签: c++ string const

char* foo = "fpp"; //compile in vs 2010 with no problem

我虽然字符串文字是const char * type 并且const类型不能分配给非const类型 所以我希望上面的代码失败或者我错过了什么?

编辑:对不起,伙计们,我完全忘记了编译器也会发出警告 我一直在查看错误列表。
我忘了检查一下。

Edit2:我将项目警告级别设置为EnableAllWarnings(/ Wall),并且没有任何警告。
所以我的问题仍然有效。

7 个答案:

答案 0 :(得分:6)

C ++ 03弃用 [Ref 1] 使用不带const关键字的字符串文字。

[参考1] C ++ 03标准:§4.2/ 2

  

不是宽字符串文字的字符串文字(2.13.4)可以转换为“指向字符的指针”的右值;可以将宽字符串文字转换为“指向wchar_t的指针”类型的右值。在任何一种情况下,结果都是指向数组第一个元素的指针。仅当存在明确的适当指针目标类型时才考虑此转换,而不是在通常需要从左值转换为右值时。 [注意:此转化已弃用。见附录D.]为了在重载决策(13.3.3.1.1)中进行排序,这种转换被认为是一个数组到指针的转换,然后是一个限定转换(4.4)。 [示例:“abc”转换为“指向const char的指针”作为数组到指针的转换,然后转换为“指向char的指针”作为限定转换。 ]

C ++ 11简单地删除了上述引用,这意味着它在C ++ 11中是非法代码。

在C ++ 03之前,C ++在没有const关键字的情况下派生了字符串文字的声明,请注意,这在C中完全有效。

答案 1 :(得分:4)

据我了解,在C中,在添加const之前,这是将字符串分配给指针的方法。

在C ++中,这是已弃用的行为,但仍允许保持向后兼容性。所以不要使用它。

事实上,我相信C ++ 11它完全无效。

答案 2 :(得分:2)

不完全。字符串文字可分配给char*类型。永远不应修改字符串文字。

这种奇怪的情况是为了与const存在之前的程序向后兼容。

答案 3 :(得分:1)

gcc -std=c++0x警告:

  

a.cpp:5:14:警告:不推荐将字符串常量转换为' char *' [-Wwrite串]

所以,这仍然是允许的,但是不推荐使用,因为文字字符串是const。

答案 4 :(得分:1)

没有const类型的东西。 Const关键字是所谓的类型限定符。它可以应用于任何指针类型,只是意味着不应修改指针指向的值。

您也可以通过以下方式将const限定符应用于指针引用:

char* const p ="aaa";

这将保护指针变量不会指向另一个字符串。

答案 5 :(得分:1)

有一种特殊的隐式转换支持这一点,因为它是遗留代码中常见的习惯用法(通常在const存在之前编写)。您的字符串文字的类型是char const[],您应该只使用它。一个好的编译器会在上面发出警告,因为转换从引入它的那一刻起就被弃用了。

请注意,这与C不同,其中字符串文字的类型为char[](但尝试修改它仍然是未定义的行为)。

答案 6 :(得分:1)

你在谈论C字符串,它实际上是char的向量。在C ++中,使用类std::string,并将常量字符串创建为const std::string

无论如何,编译器在将来的程序中保留一块内存,以便存储显示在源代码中的文字字符串。这部分内存被认为是只读的,所以你应该用const char *指向它。它的大小正好是字符串的大小加上尾随零的一个额外位置,标记字符串的结尾。

编译器需要保持向后兼容性,因此他们仍然接受char *指向的文字。但是,这是误导性的,因为您不应该能够修改可以存储在嵌入式系统的ROM中的内存。

在我的系统中,我使用了clang:

$ clang --version
Ubuntu clang version 3.0-6ubuntu3 (tags/RELEASE_30/final) (based on LLVM 3.0)
Target: i386-pc-linux-gnu
Thread model: posix

在clang C编译器中,此代码编译时没有错误:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char * str = "Hello, World!";

    printf( "%s", str );

    return EXIT_SUCCESS;
}

但是,当编译为C ++程序时,完全相同的代码(稍作修改,例如标题名称)会抛出以下警告:

kk.cpp:6:15: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
        char * str = "Hello, World!";
                     ^
1 warning generated.

希望这有帮助。