【问题标题】:char* vs const char* in CC 中的 char* 与 const char*
【发布时间】:2020-01-09 02:30:24
【问题描述】:
char* str ="Hello";

在上面的代码中,文字“Hello”存储在......在 DATA 段中,它是只读的。 所以总是声明它不是更好吗:

const char* str = "Hello";

避免不正确的代码如:

*(str+1) = 't';

【问题讨论】:

  • 在较新版本的编译器中,对于第一种语法,您至少会收到警告。
  • 数据段不是只读的,所以在有只读内存段的系统上,可能不会存储在那里。
  • 顺便说一句,没有人真的*(str+1),除了那些没有意识到str[1]指针操作而不是数组的人一。
  • @nabroyan:Clang 和 x86_64 的 GCC 都没有给出这样的警告,即使是 -Wall。事实上,除了 AVR gcc 之外,Godbolt 上的编译器都没有给出这样的警告。你会想到 C++ 吗?
  • @EricPostpischil:是的,我的评论与 C++ 有关。要么我没有注意标签,要么后来 C++ 从标签中删除了。

标签: c pointers c-strings string-literals const-correctness


【解决方案1】:

是的,最好将指向字符串文字的指针声明为const char *。 “literal”这个名字非常强烈地表明这是应该是不可变的。不幸的是,C 将字符串文字视为char 的数组,而不是const char,并且与数字文字不同,字符串文字的存储必须从某个地方分配。不能保证此存储将取自 .rodata 之类的只读段 - 我过去曾使用过字符串文字可写的实现。

尝试修改字符串文字内容的行为是未定义 - 该语言不要求编译器或运行时环境以任何特定方式处理这种情况。您可能遇到运行时错误,或者字符串可能保持不变,或者字符串可能被修改,任何完全不同的事情都可能发生。

因此,通过将指针声明为const char *,您至少可以让意外通过该指针修改文字变得更加困难。请记住,const 并不的意思是“把这个东西放在只读内存中”——它只意味着“如果有人试图修改这个东西,就会发出诊断”。

【讨论】:

    【解决方案2】:

    "Hello" 存储在 ... DATA 段中

    "DATA" 或.data 将指代具有静态存储持续时间的初始化读/写变量所在的段。字符串文字不存储在那里,但更有可能存储在名为 .rodata 的东西中,或者可能与代码一起存储在 .text 中。 见String literals: Where do they go?

    所以总是声明它不是更好吗:const char* str = "Hello";

    是的,您应该始终 const 限定指向字符串文字的指针。这在 C 中被普遍认为是最佳实践(并且在 C++ 中是强制性的)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      相关资源
      最近更新 更多