Jonathan Mee
I know that a `const char*` is a pointer to a constant character, and that a `const char[]` is an array of constant characters.
That said what should make me prefer declaring as one type over the other? Are there any good heuristics for directing that decision?
Top Answer
Jonathan Mee
The simple answer is that when declaring a variable you should prefer a `const char[]`.
---
To understand this let's take 2 character strings: `const char* ptr = "lorem"` and `const char arr[] = "ipsum"` And lets pass them into this function:
template <typename T>
void Output(const void* pv, const char pc[], T ppc) {
std::cout << "Value: " << pv << " String: " << pc << " Address: " << ppc << std::endl;
}
`Output(ptr, ptr, &ptr)` will output something like:
> Value: 00E33130 String: lorem Address: 00FBF8D8
While `Output(arr, arr, &arr)` will output something like:
> Value: 00FBF8DC String: ipsum Address: 00FBF8DC
The notable difference here is that `ptr` requires the allocation of another address. There are 3 extra expenses to this.
1. The 1^st^ is the obvious memory cost of a pointer, which one would expect that to be as simple as 8-bytes on a 64-bit architecture, [but because of relocations that can skyrocket to 32-bytes of memory](https://glandium.org/blog/?p=2361)
1. [The 2^nd^ is the hidden cost of indirection, and potential cache misses](https://eklitzke.org/declaring-c-string-constants-the-right-way)
1. The final expense is in the requirement of separately finding the end of the string pointed to by `ptr`, whereas `arr` can use the [Range Access Functions](https://en.cppreference.com/w/cpp/iterator#Range_access)
If we were to change `ptr` to a _constant_ pointer (`const char* const ptr`) the result would be the compiler optimizing away **1**, however both **2** and **3** would persist _and_ `ptr` could not be used in functions taking a `const char*`. Ultimately, when declaring variables `const char[]` is the clear choice over both `const char*` and `const char* const`.