为什么 C++ 中的字符串文字 (char*) 必须是常量?
Why do string literals (char*) in C++ have to be constants?
我最近一直在学习 C++,并意识到 C++ 中的字符串文字必须是常量,而在 C 中则不是。这是一个例子。以下代码在 C 中有效,但在 C++ 中无效:
char* str = "Hello World";
为了在 C++ 中做同样的事情,必须使用以下语句:
const char* str = "Hello World";
有人可以解释为什么吗?
C 最初没有 const
关键字,因此如果在引入关键字后将文字更改为需要 const
限定,它将破坏遗留代码。但是,C 的字符串文字是不可变的,因此更改内容是未定义的行为,即使它不是 const
限定的。
另一方面,C++ 是用 const
关键字设计的。最初,C++ 确实允许将字符串文字分配给非 const
限定的 char *
,大概是为了与现有 C 代码兼容。然而,从 C++03 标准开始,他们决定弃用此功能,而不是让这种不和谐永远持续下去。我猜想依赖非 const
限定 char *
指向字符串文字的遗留 C++ 代码的数量足够小,值得权衡。
扩展一下 Christian Gibbons 的回答...
在 C 中,像 "Hello World"
这样的字符串文字存储在 char
的数组中,这样它们在程序的整个生命周期内都是可见的。字符串文字 应该 是不可变的,一些实现会将它们存储在只读内存段中(这样尝试修改文字的内容将触发运行时错误)。一些实现不会,并且尝试修改文字的内容可能不会触发运行时错误(它甚至可能看起来按预期工作)。 C 语言定义保留了行为 "undefined" 以便编译器可以自由地处理它认为合适的情况。
在 C++ 中,字符串文字存储在 <em>const</em> char
数组中,因此任何修改文字内容的尝试都会触发诊断 在编译时 。
正如 Christian 指出的那样,const
关键字最初不是 C 的一部分。但是,它最初是 C++ 的一部分,它使使用字符串文字更加安全。
记住const
关键字不表示"store this in read-only memory",它只表示"this thing may not be the target of an assignment."
还要记住,除非它是 sizeof
或一元 *
运算符的操作数,或者是用于在声明中初始化字符数组的字符串文字,否则 [=44= "N-element array of T
" 类型的 ]expression 将被转换 ("decay") 为 "pointer to T
" 类型的表达式,表达式的值将是数组。
在 C++ 中,当您编写
const char *str = "Hello, world";
将字符串第一个字符的地址存储到str
。您可以将 str
设置为指向 不同的 字符串文字:
str = "Goodbye cruel world";
但是你不能做的是修改字符串的内容,比如
str[0] = 'h';
或
strcpy( str, "Something else" );
我最近一直在学习 C++,并意识到 C++ 中的字符串文字必须是常量,而在 C 中则不是。这是一个例子。以下代码在 C 中有效,但在 C++ 中无效:
char* str = "Hello World";
为了在 C++ 中做同样的事情,必须使用以下语句:
const char* str = "Hello World";
有人可以解释为什么吗?
C 最初没有 const
关键字,因此如果在引入关键字后将文字更改为需要 const
限定,它将破坏遗留代码。但是,C 的字符串文字是不可变的,因此更改内容是未定义的行为,即使它不是 const
限定的。
C++ 是用 const
关键字设计的。最初,C++ 确实允许将字符串文字分配给非 const
限定的 char *
,大概是为了与现有 C 代码兼容。然而,从 C++03 标准开始,他们决定弃用此功能,而不是让这种不和谐永远持续下去。我猜想依赖非 const
限定 char *
指向字符串文字的遗留 C++ 代码的数量足够小,值得权衡。
扩展一下 Christian Gibbons 的回答...
在 C 中,像 "Hello World"
这样的字符串文字存储在 char
的数组中,这样它们在程序的整个生命周期内都是可见的。字符串文字 应该 是不可变的,一些实现会将它们存储在只读内存段中(这样尝试修改文字的内容将触发运行时错误)。一些实现不会,并且尝试修改文字的内容可能不会触发运行时错误(它甚至可能看起来按预期工作)。 C 语言定义保留了行为 "undefined" 以便编译器可以自由地处理它认为合适的情况。
在 C++ 中,字符串文字存储在 <em>const</em> char
数组中,因此任何修改文字内容的尝试都会触发诊断 在编译时 。
正如 Christian 指出的那样,const
关键字最初不是 C 的一部分。但是,它最初是 C++ 的一部分,它使使用字符串文字更加安全。
记住const
关键字不表示"store this in read-only memory",它只表示"this thing may not be the target of an assignment."
还要记住,除非它是 sizeof
或一元 *
运算符的操作数,或者是用于在声明中初始化字符数组的字符串文字,否则 [=44= "N-element array of T
" 类型的 ]expression 将被转换 ("decay") 为 "pointer to T
" 类型的表达式,表达式的值将是数组。
在 C++ 中,当您编写
const char *str = "Hello, world";
将字符串第一个字符的地址存储到str
。您可以将 str
设置为指向 不同的 字符串文字:
str = "Goodbye cruel world";
但是你不能做的是修改字符串的内容,比如
str[0] = 'h';
或
strcpy( str, "Something else" );