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

Doing this in C ++

char* cool = "cool"; 

compiles fine, but gives me a warning:

deprecated conversion from string constant to char *.

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

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

+63
c ++ c c-strings
Jul 25 '16 at 17:37
source share
7 answers

Yes, this declaration is bad practice as it allows many ways to accidentally provoke Undefined behavior by writing to a string literal, including:

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

This is fine, on the other hand, as it allocates a non-constant array of characters:

 char cool[] = "cool"; 
+58
Jul 25 '16 at 17:40
source share

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

String literals are stored in read-only memory whenever possible; their type is properly const -qualified. C, but not C ++, includes backward compatibility bonuses, where the compiler gives them the type char [N] , even if they are stored in read-only memory. This is because string literals are older than const . const was invented in anticipation of what is now called "C89" - an earlier form of the "K & R" language did not have this.

Some C compilers include an additional mode in which the backward compatible wart is disabled and char *foo = "..."; will provide you with the same or similar diagnostics as in C ++. GCC runs this -Wwrite-strings mode. I highly recommend it for new code; however, including it for old code may require a huge number of tools for very little benefit.

+16
Jul 25 '16 at 17:45
source share

This is bad. This is very bad. To the fact that this cannot be done in C ++ 11.

Modifying the memory of a string literal is undefined behavior.

+14
Jul 25 '16 at 17:39
source share

First, char* cool = "cool"; not standard C ++. The string literal is of type const char[n] . Thus, the above line of code violates const-correctness and should not be compiled. Some compilers, such as GCC, allow this, but raise a warning, as this is a restriction from C. MSVC throws an error because it is an error.

Secondly, why not let the compiler work for you? If it is marked const , then you will get a good compiler error if you accidentally try to change it. If you don't, you can get a very nasty runtime error, which can be a lot harder to find.

+13
Jul 25 '16 at 17:41
source share

This is bad because string constants can only be contained once per binary (keyword: stringtable, .strtab ). For example. at

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

both variables can point to the same memory location. Changing the contents of one of them can change the other, so after

 strcpy(nothot, "warm"); 

your cool will become warm.

In short, this behavior is undefined.

+7
Jul 25 '16 at 17:51
source share

This is a string literal, so it must be persistent, as the memory may be in a read-only section. If you have char cool[] = "cool"; , then this is not a problem, the memory belongs to you.

+6
Jul 25 '16 at 17:40
source share

char * cool = "cool"

"cool" will be stored in a read-only block (usually in a data segment) that is shared between functions. If you try to change the line "cool" to the point cool, you will get an error, such as a segment error when starting the program. If you use const char* cool = "cool" , you will get a compilation error message if you try to change the line.
You can read this page for more information http://www.geeksforgeeks.org/storage-for-strings-in-c/

+2
Jul 26 '16 at 6:27
source share



All Articles