2

I am a C++ newbie. Although many similar questions have been asked and answered, I still find these concepts confusing. I know

char c='a'            // declare a single char c and assign value 'a' to it
char * str = "Test";  // declare a char pointer and pointing content str, 
                      // thus the content can't be modified via point str
char str1[] = "Test"; // declare a char array str1 and assign "Test" to it
                      // thus str1 owns the data and can modify it

my first question is char * str creates a pointer, how does char * str = "Test"; work? assign a string literal to a pointer? It doesn't make sense to me although it is perfectly legal, I think we can only assign an address to a pointer, however "Test" is a string literal not an address.

Second question is how come the following code prints out "Test" twice in a row?

char str2[] = {'T','e','s','t'};  // is this line legal? 
                                 // intializing a char array with initilizer list, seems to be okay to me
cout<<str2<<endl;               // prints out "TestTest"

why cout<<str2<<endl; prints out "TestTest"?

Albert G Lieu
  • 891
  • 8
  • 16
  • 1
    Related: [What is the difference between `char s[]` and `char* s`?](https://stackoverflow.com/q/1704407/11082165), [Why do string literals (char*) in C++ have to be constants?](https://stackoverflow.com/q/61601872/11082165), [What is the datatype of string literal in C++?](https://stackoverflow.com/q/12517983/11082165) – Brian61354270 Feb 18 '22 at 19:12
  • @FrançoisAndrieux For ````char * str = "Test";````, in Clion, it did not even throw an warning, in ubuntu terminal, compiler gives an warning saying ````warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]````, but it still runs fine. My g++ is 9.3.0 – Albert G Lieu Feb 18 '22 at 19:16
  • 1
    Re: "why `cout< – Brian61354270 Feb 18 '22 at 19:17
  • Sometimes it's good practice to check your code with an online compiler, such as [ideone](https://ideone.com/l/cpp), and see if you get the same result. You can even share it here – polfosol ఠ_ఠ Feb 18 '22 at 19:19

1 Answers1

2

char * str = "Test"; is not allowed in C++. A string literal can only be pointed to by a pointer to const. You would need const char * str = "Test";.

If your compiler accepts char * str = "Test"; it is likely outdated. This conversion has not been allowed since C++11 (which came out over 10 years ago).


how does char * str = "Test"; work?

String literals are implicitly convertible to a pointer to the start of the literal. In C++ arrays are implicitly convertible to pointer to their first element. For example int x[10] is implicitly convertible to int*, the conversion results in &(x[0]). This applies to string literals, their type is a const array of characters (const char[]).


how come the following code prints out "Test" twice in a row?

In C++ most features related to character strings assume the string is null terminated, which is implied in string literals. You would need {'T','e','s','t','\0'} to be equivalent to "Test".

François Andrieux
  • 28,148
  • 6
  • 56
  • 87
  • ````char * str = "Test"; ```` seems to be acceptable everywhere, also here https://ideone.com/l/cpp, no error or warning, my g++ and gcc are 9.3.0. Is this outdated? – Albert G Lieu Feb 18 '22 at 19:24
  • 2
    @AlbertGLieu It hasn't been allowed since C++11. See [String Literal](https://en.cppreference.com/w/cpp/language/string_literal#Notes) : "String literals are not convertible or assignable to non-const CharT*. An explicit cast (e.g. const_cast) must be used if such conversion is wanted. (since C++11)" This is not my opinion, it is factually not allowed by the language. By default even gcc 9.3.0 produces a warning, so your configuration must be silencing it : https://godbolt.org/z/aG54csajr – François Andrieux Feb 18 '22 at 19:26
  • @ François Andrieux thank you so much for sharing you knowledge and your precious time. – Albert G Lieu Feb 18 '22 at 19:29
  • 2
    @AlbertGLieu GCC provides a lot of non-standard extensions that are enabled by default. It will allow all sorts of code that is not normally allowed in C++ to compile and run, but it leaves the code non-portable (you have GCC C++ code, not C++ code). The most notorious is probably variable length arrays. I recommend disabling these extension by using the compilation flags `-pedantic` and `-Werror`. – François Andrieux Feb 18 '22 at 19:38