问题
So this article is discussing the use of declaring a string literal like const char* foo = "foo"
it ends with the claim:
const char *foo = "foo";
is almost never what you want. Instead, you want to use one of the following forms:
- For a string meant to be exported:
const char foo[] = "foo";
- For a string meant to be used in the same source file:
static const char foo[] = "foo";
- For a string meant to be used across several source files for the same library:
__attribute__((visibility("hidden"))) const char foo[] = "foo";
My understanding here is that const char* const foo = "foo"
is equivalent to const char foo[] = "foo"
simply because we're talking about a C-string pointer that can never be changed to point at anything else, whereas const char* foo = "foo"
could be used to point at any other C-String.
Is this an accurate synopsis? Always use either const char* const
or const char[]
?
回答1:
Let's get pedantic here.
char const * const p_foo = "foo";
The above defines a {constant} pointer to the {constant} character literal "foo". The pointer is to the single first character of the character literal.
const char bar[] = "bar";
- The above defines a character array.
- The character array is *read-only".
- The character array is the length of the text literal "bar" plus a nul terminator (4 characters).
- The contents of the text literal are copied into the array. (The compiler may optimize this step away).
Fundamentally, you have the difference between a pointer to the first character of a literal and an array.
The pointer is pointing to a single character. Incrementing the pointer may not point to a valid entity (since it is not an array, but a pointer to a single datum). There is an underlying assumption that the pointer can be incremented to the next character.
With an array you know that there are more than one character sequentially in memory (provided the array is of length 2 or more). You don't know if there is a terminating nul in the sequence (collection). You can assume that, but an array of characters does not guarantee that.
Usages
With the array declaration, the length of the text is known at compile time.
With the pointer declaration, you would need to use strlen
to determine the length of the text at run-time. The run-time code doesn't know the length of the target data string; only a length of 1 can be guaranteed.
Sometimes, using static
and const
can help the compiler optimize.
For example:
static const char moo[] = "moo";
allows the compiler to access the text directly without creating an array variable and copying the text into the variable.
In a function that receives a pointer to a character, you can't guarantee that the pointer points to a valid location (the content of the pointer can be invalid).
Each declaration has its benefits and side-effects.
The choice is yours.
回答2:
I do agree that an array decays into a pointer when being evaluated but there are a few functionalities that come only with an array. For example when you declare an array you have additional information as to what the size of the array is.
Also, for the fixed array case, memory is allocated specifically for foo. So you are allowed to change the contents of the array like you usually can and the array is destroyed, deallocating memory when it runs out of scope (typical local variable).
When you define it as a pointer, the compiler places foo into read-only memory, and then points to it (usually). Note that this is why most cases constant strings are defined as char* and even the compiler would warn you when you set it as a non constant pointer.
#include <iostream>
int main()
{
char* a = "foo";
return 0;
}
This code would throw you a warning like:
ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings] char* a = "foo";
and any change you try to make to the string would typically lead to a segmentation fault.
来源:https://stackoverflow.com/questions/50536666/difference-between-const-char-and-const-char