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/。