声明一个没有 const 的 C 风格字符串不好吗?如果是这样,为什么?

Is it bad to declare a C-style string without const? If so, why?

在 C++ 中执行此操作

char* cool = "cool";

编译正常,但给了我一个警告:

deprecated conversion from string constant to char*.

我永远不会故意在 std::string 上使用 C 风格的字符串,但以防万一我被问到这个问题:

在没有 const 修饰符的情况下声明 C 风格的字符串是不好的做法吗?如果是,为什么?

不好。这很糟糕。到目前为止,这在 C++11 中是不可能再做的了。

修改字符串文字的内存是未定义的行为。

它是一个字符串文字,因此它应该是常量,因为内存可能位于只读部分。如果你有 char cool[] = "cool"; 那没问题,内存是你的。

是的,这个声明是不好的做法,因为它允许通过写入字符串文字来意外引发未定义行为的多种方式,包括:

cool[0] = 'k';
strcpy(cool, "oops");

另一方面,这很好,因为它分配了一个非常量字符数组:

char cool[] = "cool";

首先,char* cool = "cool"; 不是标准的 C++。字符串文字的类型为 const char[n]。所以上面的代码行破坏了常量正确性,不应该编译。一些编译器(如 GCC)允许这样做,但会发出警告,因为它是 C 的保留。MSVC 会发出错误,因为它是一个错误。

第二,为什么不让编译器为你工作?如果它被标记为 const 那么如果您不小心尝试修改它,您将得到一个很好的编译器错误。如果你不这样做,那么你会得到一个非常讨厌的 运行 时间错误,它很难找到。

是的,在 C++ 中,您应该始终引用具有 const char *const char [N] 类型变量的字符串文字。这也是编写新 C 代码时的最佳实践。

尽可能将字符串文字存储在只读存储器中;他们的类型是 const 合格的。 C,但不是 C++,包括一个向后兼容性的缺点,编译器给它们类型 char [N] ,即使 它们存储在只读内存中。这是因为字符串文字早于 const 限定符。 const 是在 运行-直到现在所谓的 "C89" 之前发明的——早期的 "K&R" 形式的语言没有它。

一些 C 编译器包括一个可选模式,在该模式下,向后兼容性 wart 被禁用,并且 char *foo = "..."; 将为您提供与 C++ 中相同或相似的诊断。 GCC 拼写此模式 -Wwrite-strings。我强烈推荐它用于新代码;然而,为旧代码打开它可能需要大量的 scutwork,但收效甚微。

这很糟糕,因为每个二进制文件可能只包含一次字符串常量(关键字:stringtable,.strtab)。例如。在

char *cool = "cool";
char *nothot = "cool";

两个变量可以指向相同的内存位置。修改其中一个的内容可能也会改变另一个,所以 after

strcpy(nothot, "warm");

你的 cool 变成 "warm"。

简而言之,这是未定义的行为。

char* cool = "cool"

"cool" 将存储在函数之间共享的只读块(通常在数据段中)中。如果你试图通过点酷来修改字符串"cool",当程序是运行时,你会得到一个错误,比如segment error。如果使用const char* cool = "cool",尝试修改字符串,编译时会报错
您可以阅读此页面以获取更多信息 http://www.geeksforgeeks.org/storage-for-strings-in-c/

为字符串编写 const 是一个好习惯(尤其是当您使用字符串文字时),但在 C 中几乎没有什么区别,它会在 C++ 中抛出警告,但在 C 中不会抛出警告,还要记住一些编译器假设 .c 扩展名简单地作为 c 而 .C 作为 c++,所以在这种情况下要小心 points.otherwise 在字符串的情况下使用 const 是一个很好的做法,所以错误地你不要更改字符串或尝试更改存储在只读内存中的字符串文字。