为什么允许使用 char *s = "hello"?

5
char *s = "hello";

上面的代码在程序的只读部分分配了6个字节来存储字符串“hello”(我忘记了这个部分的名称)。然后,s被初始化为指向字符串“hello”的第一个字符。修改字符串“hello”是未定义的行为。此外,“hello”本身在本质上是常量。程序没有权限更改只读段。
我正在使用MS VC++ 2010 Express。我的问题是,为什么编译器允许s,它是一个char *,指向常量字符串?难道不应该有编译器错误吗?编译器不应该强制我们使用const char *s =“hello”;而不是char *s =“hello”;吗?
谢谢。
2个回答

5
在C语言中,"hello"的类型为char[]。但在C++中不是这样的。参见这个问题

@samold,我不确定你的意思。如果你的意思是我应该简单地将问题标记为重复,那么我的感觉是这个问题足够不同,尽管那里的非常完整的答案涵盖了这里的问题。无论如何,如果其他人认为这是一个重复的问题,他们可以关闭它。 - Pascal Cuoq
抱歉伙计,我只是喜欢Phil Ken Sebben. :) - sarnold
@samold 哦,我明白了。这个头像图片是由另一个StackExchange用户选择的,他的OpenID不情愿地与这个共享账户绑定在了一起。 - Pascal Cuoq
太可怕了。请标记给管理员注意,他们过去已经处理过类似的事情了... - sarnold
2
为避免混淆,它具有类型char[N],其中N是字面量的长度+1。 - Johannes Schaub - litb
@Complicatedseebio:确实,可以标记为需要关注的问题或者(更好的方式)发送电子邮件请求帮助。当我第一次加入SO时,我的账户因为cookie问题而无法访问,直到我设置了OpenID后他们立即解决了这个问题。如果他们没有如此迅速地响应,我可能今天就不会继续使用SO了。 - R.. GitHub STOP HELPING ICE

2
这是在C引入const限定符之前的事情。C标准机构对现有代码非常保守。语言的任何改进都必须以不破坏先前标准版本编写的任何符合性代码为前提。
如果这样的事情导致不良后果,那么该功能将被弃用,并且可能在多年后进行更改。
对于字符串字面值的具体特性,其类型为char[]而不是char const[],这对初学者来说确实是一个陷阱。从一开始就养成使用char const*引用此类字符串的习惯。
编辑:关于编译器是否应该警告,我认为这很难追踪。在这段代码中。
int main(void) {
  "hello"[0] = 'H';
  char * a = "hoho";
  a[0] = 'H';
}

gcc只在第一个赋值语句上给出了警告,而在第二个赋值语句上没有。clang根本没有捕捉到。


他们这样做是正确的,但在这种情况下,发出警告就足够了。这并不是我认为的“破坏旧代码”。 - glglgl
1
准确地说,与字符串字面值相关联的数组是类型为char[N]的,但任何修改它的尝试都具有未定义的行为。(例如,gcc可以使用-Wwrite-strings选项将字符串字面值视为const,但这是不符合标准的。) - Keith Thompson
@glglgl,我完全同意,但不认为这是微不足道的。请看我的编辑。 - Jens Gustedt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接