char* foo = "fpp"; //compile in vs 2010 with no problem
我虽然字符串文字是const char * type 并且const类型不能分配给非const类型 所以我希望上面的代码失败或者我错过了什么?
编辑:对不起,伙计们,我完全忘记了编译器也会发出警告
我一直在查看错误列表。
我忘了检查一下。
Edit2:我将项目警告级别设置为EnableAllWarnings(/ Wall),并且没有任何警告。
所以我的问题仍然有效。
答案 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.
希望这有帮助。