Most of the time I see constant C-strings defined as:
static char const* MY_CONSTANT = "Hello World";
However, the pointer itself is not const
. Wouldn't it be more appropriate to do it like below?
static char const* const MY_CONSTANT = "Hello World";
There are 2 goals with constant globals like this, I think:
I simply assumed these 2 goals were needed when defining constant strings.
Another interesting thing is that I am allowed to do this:
int main()
{
auto MY_CONSTANT = "";
MY_CONSTANT = "Another String";
}
This tells me that auto
deduces the string as char const*
and not char const* const
.
So I have two main questions:
auto
, it makes sense why it chooses char const*
(because it's the array of data that's constant, not the pointer itself). Could I make auto
deduce to char const* const
or can I change the code to make it result in such a type?A string constant is an arbitrary sequence of characters that are enclosed in single quotation marks (' ').
Variables can be declared as constants by using the “const” keyword before the datatype of the variable. The constant variables can be initialized once only. The default value of constant variables are zero. A program that demonstrates the declaration of constant variables in C using const keyword is given as follows.
A String Literal, also known as a string constant or constant string, is a string of characters enclosed in double quotes, such as "To err is human - To really foul things up requires a computer." String literals are stored in C as an array of chars, terminted by a null byte.
A string constant is an array of characters that has a fixed value enclosed within double quotation marks ( “ “ ). For example, “DataFlair”, “Hello world!”
Well if it a truly a constant then constexpr would be the C++11 way to do this:
constexpr char const* MY_CONSTANT = "Hello World";
The first example:
static char const* MY_CONSTANT = "Hello World";
just says I have a pointer to a char const that has static storage duration, which if it is outside of a function would make it a global.
If we required the pointer to also be const then we need the second form your introduced. It all depends on whether the pointer is indeed supposed to const or not. In most cases, the reason your see code without the top-level const is because they just forgot to put it in not because they did not mean the pointer to also be const.
Where static makes a difference for example if whether you want a const member to be per-instance or per-class:
class A
{
char const* const const_per_instance = "Other Const String";
public:
constexpr static char const* const const_per_class = "Hello World" ;
};
If we require the const to be per-class then we need to use static otherwise not. The example changes slightly if you are not allowed to use constexpr:
class A
{
char const* const const_per_instance = "Other Const String";
public:
static char const* const const_per_class ;
};
char const* const A::const_per_class = "Hello World" ;
but the essence is the same just the syntax is different.
For your second question as Gotw #92 says auto drops top level const, one example given is as follows:
const int ci = val;
auto g = ci;
and it says:
The type of g is int.
Remember, just because ci is const (read-only) doesn’t have any bearing on whether we want g to be const. It’s a separate variable. If we wanted g to be const, we would have said const auto as we did in case c above
the example that is being referred to is as follows:
int val = 0;
//..
const auto c = val;
constexpr auto& MY_CONSTANT = "Hello World";
const char (&)[12]
constexpr
and can be used in headersIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With