26

I'm confused about the datatype of a string literal. Is it a const char * or a const char?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Vihaan Verma
  • 12,815
  • 19
  • 97
  • 126
  • See my answer http://stackoverflow.com/questions/12451496/what-is-the-data-type-for-a-string/12452097#12452097 to similar question. – PiotrNycz Sep 20 '12 at 17:52
  • 12
    judging by the number of people that have this wrong (thinking its const char*) I fail to see why this is being down-voted. Apparently its a pretty damn good question when half the respondents don't know the answer. – WhozCraig Sep 20 '12 at 17:52
  • 5
    @CraigNelson, I've seen way too many people with 10s of k of rep get it wrong over the last while. – chris Sep 20 '12 at 17:54
  • @CraigNelson i think that this is because the C++ behaviour on this matter is pretty unique considering the most popular languages on the scene, from C to Java string literals are treated like pointers or putted in a pool and then used by reference. probably there is a lot of confusion because of this unique behaviour. – Ken Sep 20 '12 at 17:57
  • 2
    @Ken The only difference between C and C++ in this regard is the `const` qualifier. C treats it as a `char[N]` instead of `const char[N]` – Praetorian Sep 20 '12 at 18:00
  • @Prætorian in C a string like "Hello" is a pointer, also arrays and pointers adopt the arithmetic, you can assign "Hello" to a pointer in C. – Ken Sep 20 '12 at 18:08
  • @Ken, You can do that in C++. Arrays decay into pointers. Arrays don't offer arithmetic like pointers do. – chris Sep 20 '12 at 18:12
  • 2
    @Ken, Here's proof they're arrays in C, using the same method Seth did for C++: http://liveworkspace.org/code/198d050af0d08a9fc86ac17c144d581d. If it was a pointer, the size would very likely not be 11. You can put one with a different length in there alongside the first if you want to eliminate weird pointer sizes. – chris Sep 20 '12 at 18:16
  • I think it is `const char (&) [N]` instead. – Hải Phạm Lê Dec 27 '22 at 10:21

2 Answers2

30

It is a const char[N] (which is the same thing as char const[N]), where N is the length of the string plus one for the terminating NUL (or just the length of the string if you define "length of a string" as already including the NUL).

This is why you can do sizeof("hello") - 1 to get the number of characters in the string (including any embedded NULs); if it was a pointer, it wouldn't work because it would always be the size of pointer on your system (minus one).

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
  • 6
    To back it up, *A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration (3.7).* – chris Sep 20 '12 at 17:48
  • Won't disagree. However, when a string constant is used in template matching it appears to be as `char [N]` (and not `char const[N]`), at least in one usage... The context is: I have templ. mem. func `func(T const &x)` instantiated as `A.func("string")` and it matches with T as `char [7]`. Odd. Or perhaps because the parameter x is a 'const ref to an array [7] of const char' the second const is removed as redundant, and the first is not part of T. g++ 4.6.3 – greggo Feb 11 '14 at 16:04
  • 1
    @greggo: C string literals are `char[]`. C++ up to and including C++03 *allows* (but deprecates) assigning a string literal to a non-const `char*` as well, although C++ string literals were *always* `const`. Starting with C++11, assigning a string literal to a non-const `char *` is *disallowed* without explicit casting. – DevSolar Sep 30 '14 at 08:15
  • @DevSolar Thanks , you made it stick in my mind , just one question, in C is string literal convertible to char * ? – Suraj Jain Dec 27 '16 at 10:29
  • 1
    @SurajJain: *Any* array is "convertible" to a pointer to its first element. But you lose the ability to determine the size of the array via `sizeof`. – DevSolar Dec 27 '16 at 10:41
8

"Hello world" is const char[12] (eleven characters plus '\0' terminator).

L"Hello world" is const wchar_t[12].

And since C++14, "Hello world"s is std::string.

Also note the u8"", u"" and U"" string literal notations added by C++11, which specify UTF-8, UTF-16 and UTF-32 encoding, respectively. The encoding of non-qualified string literals (i.e. "" and L"") is (and always was) implementation-defined.

DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • Just a noob question: Does adding `s` to a string literal make it of type `std::string`? If not, why is it being used? – asn Jul 27 '19 at 17:18
  • @AjaySinghNegi Indeed `""s` is a way to have a [std::string literal](https://en.cppreference.com/w/cpp/string/basic_string/operator""s). You can have [user-defined literals](https://en.cppreference.com/w/cpp/language/user_literal) since C++11. – DevSolar Jul 27 '19 at 17:25
  • In cpp, doesn't a string literal implicitely convert to string if `string s = "abc;` is written. If Yes, then why is `""s` used? – asn Jul 27 '19 at 17:56
  • @AjaySinghNegi There are several reasons. One is that there is no conversion taking place. The literal **is** of type `std::string`. This can make a difference e.g. in template context. – DevSolar Jul 27 '19 at 18:01