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

时间:2021-07-31 22:26:04

Doing this in C++

在c++中这样做

char* cool = "cool";

compiles fine, but gives me a warning:

编译好,但给我一个警告:

deprecated conversion from string constant to char*.

不赞成将字符串常量转换为char*。

I would never willfully use a C-style string over std::string, but just in case I'm asked this question:

我永远不会在std上使用c样式的字符串::string,但如果我被问到这个问题:

is it bad practice to declare a C-style string without the const modifier? If so, why?

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

7 个解决方案

#1


58  

Yes, this declaration is bad practice, because it allows many ways of accidentally provoking Undefined Behavior by writing to a string literal, including:

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

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

On the other hand, this is perfectly fine, since it allocates a non-const array of chars:

另一方面,这是完全可以的,因为它分配了一个非const的chars数组:

char cool[] = "cool";

#2


16  

Yes, in C++ you should always refer to string literals with variables of type const char * or const char [N]. This is also best practice when writing new C code.

是的,在c++中,您应该总是使用类型const char *或const char [N]的变量来引用字符串常量。这也是编写新的C代码时的最佳实践。

String literals are stored in read-only memory, when this is possible; their type is properly const-qualified. C, but not C++, includes a backward compatibility wart where the compiler gives them the type char [N] even though they are stored in read-only memory. This is because string literals are older than the const qualifier. const was invented in the run-up to what's now called "C89" -- the earlier "K&R" form of the language did not have it.

在可能的情况下,字符串文本存储在只读内存中;他们的类型是正确的。C,但不是c++,包括一个向后兼容的缺陷,编译器会给它们提供类型char [N],尽管它们存储在只读内存中。这是因为字符串文字比const限定符更古老。const是在“C89”(早期的“K&R”语言没有C89)出现之前发明的。

Some C compilers include an optional mode in which the backward compatibility wart is disabled, and char *foo = "..."; will get you the same or a similar diagnostic that it does in C++. GCC spells this mode -Wwrite-strings. I highly recommend it for new code; however, turning it on for old code is liable to require an enormous amount of scutwork for very little benefit.

有些C编译器包含一个可选模式,其中禁用向后兼容疣,char *foo = "…";将得到与c++中相同或类似的诊断。GCC使用这种模式- wwrite -string。我强烈推荐它用于新代码;但是,为旧的代码打开它可能需要大量的scutwork,而获得的好处却很少。

#3


14  

It's bad. It's very bad. To the point this isn't possible to do anymore in C++11.

它是坏的。这非常糟糕。在c++ 11中,这是不可能的。

Modifying the memory of a string literal is undefined behaviour.

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

#4


13  

First, char* cool = "cool"; is not standard C++. A string literal has the type of const char[n]. So the above line of code breaks const-correctness and should not compile. Some compilers like GCC allow this but issue a warning as it is a hold over from C. MSVC will issue a error since it is a error.

首先,char* cool = "cool";不是标准的C + +。字符串文字具有const char[n]的类型。因此,上面一行代码违反了const-correct,不应该编译。有些编译器,如GCC,允许这样做,但是会发出警告,因为这是C. MSVC的错误,所以会发出一个错误。

Second, why not let the compiler work for you? If it is marked const then you will get a nice compiler error if you accidentally try to modify it. If you do not then you can get a really nasty run time error which can be much harder to find.

其次,为什么不让编译器为您工作呢?如果它被标记为const,那么如果您不小心试图修改它,您将得到一个很好的编译错误。如果您不这样做,那么您将会得到一个非常严重的运行时错误,这将很难找到。

#5


7  

It is bad because string constants might be contained only once per binary (keyword: stringtable, .strtab). E.g. in

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

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

both variables can point to the same memory location. Modifying the contents of one of them might alter the other too, so that after

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

strcpy(nothot, "warm");

your cool becomes "warm".

冷静变得“温暖”。

In short, it is undefined behaviour.

简而言之,这是一种没有定义的行为。

#6


6  

It is a string literal, therefore it should be constant as memory might be located in read only section. If you have char cool[] = "cool"; then it's not a problem, the memory is yours.

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

#7


2  

char* cool = "cool"

char *酷=“酷”

"cool" will be stored in a read only block (generally in data segment) that is shared among functions. If you try to modify the string "cool" by the point cool you will get a error such as segment error when the program is running. If you use const char* cool = "cool", you will get a error when compile if you try to modify the string.
You can read this page for more information http://www.geeksforgeeks.org/storage-for-strings-in-c/

“cool”将存储在函数之间共享的只读块(通常是数据段)中。如果您试图修改字符串“cool”的点cool,您将得到一个错误,如程序运行时的段错误。如果您使用const char* cool =“cool”,如果您试图修改字符串,那么在编译时将会出现错误。您可以阅读此页面以获得更多信息:http://www.geeksforgeeks.org/storage- in- in- in-c/。

#1


58  

Yes, this declaration is bad practice, because it allows many ways of accidentally provoking Undefined Behavior by writing to a string literal, including:

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

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

On the other hand, this is perfectly fine, since it allocates a non-const array of chars:

另一方面,这是完全可以的,因为它分配了一个非const的chars数组:

char cool[] = "cool";

#2


16  

Yes, in C++ you should always refer to string literals with variables of type const char * or const char [N]. This is also best practice when writing new C code.

是的,在c++中,您应该总是使用类型const char *或const char [N]的变量来引用字符串常量。这也是编写新的C代码时的最佳实践。

String literals are stored in read-only memory, when this is possible; their type is properly const-qualified. C, but not C++, includes a backward compatibility wart where the compiler gives them the type char [N] even though they are stored in read-only memory. This is because string literals are older than the const qualifier. const was invented in the run-up to what's now called "C89" -- the earlier "K&R" form of the language did not have it.

在可能的情况下,字符串文本存储在只读内存中;他们的类型是正确的。C,但不是c++,包括一个向后兼容的缺陷,编译器会给它们提供类型char [N],尽管它们存储在只读内存中。这是因为字符串文字比const限定符更古老。const是在“C89”(早期的“K&R”语言没有C89)出现之前发明的。

Some C compilers include an optional mode in which the backward compatibility wart is disabled, and char *foo = "..."; will get you the same or a similar diagnostic that it does in C++. GCC spells this mode -Wwrite-strings. I highly recommend it for new code; however, turning it on for old code is liable to require an enormous amount of scutwork for very little benefit.

有些C编译器包含一个可选模式,其中禁用向后兼容疣,char *foo = "…";将得到与c++中相同或类似的诊断。GCC使用这种模式- wwrite -string。我强烈推荐它用于新代码;但是,为旧的代码打开它可能需要大量的scutwork,而获得的好处却很少。

#3


14  

It's bad. It's very bad. To the point this isn't possible to do anymore in C++11.

它是坏的。这非常糟糕。在c++ 11中,这是不可能的。

Modifying the memory of a string literal is undefined behaviour.

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

#4


13  

First, char* cool = "cool"; is not standard C++. A string literal has the type of const char[n]. So the above line of code breaks const-correctness and should not compile. Some compilers like GCC allow this but issue a warning as it is a hold over from C. MSVC will issue a error since it is a error.

首先,char* cool = "cool";不是标准的C + +。字符串文字具有const char[n]的类型。因此,上面一行代码违反了const-correct,不应该编译。有些编译器,如GCC,允许这样做,但是会发出警告,因为这是C. MSVC的错误,所以会发出一个错误。

Second, why not let the compiler work for you? If it is marked const then you will get a nice compiler error if you accidentally try to modify it. If you do not then you can get a really nasty run time error which can be much harder to find.

其次,为什么不让编译器为您工作呢?如果它被标记为const,那么如果您不小心试图修改它,您将得到一个很好的编译错误。如果您不这样做,那么您将会得到一个非常严重的运行时错误,这将很难找到。

#5


7  

It is bad because string constants might be contained only once per binary (keyword: stringtable, .strtab). E.g. in

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

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

both variables can point to the same memory location. Modifying the contents of one of them might alter the other too, so that after

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

strcpy(nothot, "warm");

your cool becomes "warm".

冷静变得“温暖”。

In short, it is undefined behaviour.

简而言之,这是一种没有定义的行为。

#6


6  

It is a string literal, therefore it should be constant as memory might be located in read only section. If you have char cool[] = "cool"; then it's not a problem, the memory is yours.

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

#7


2  

char* cool = "cool"

char *酷=“酷”

"cool" will be stored in a read only block (generally in data segment) that is shared among functions. If you try to modify the string "cool" by the point cool you will get a error such as segment error when the program is running. If you use const char* cool = "cool", you will get a error when compile if you try to modify the string.
You can read this page for more information http://www.geeksforgeeks.org/storage-for-strings-in-c/

“cool”将存储在函数之间共享的只读块(通常是数据段)中。如果您试图修改字符串“cool”的点cool,您将得到一个错误,如程序运行时的段错误。如果您使用const char* cool =“cool”,如果您试图修改字符串,那么在编译时将会出现错误。您可以阅读此页面以获得更多信息:http://www.geeksforgeeks.org/storage- in- in- in-c/。