1

What is difference between two definitions below:

    char *str1 = "string 1"; // (1)
    const char *str2 = "string 2"; // (2)

(1), is this an undefined behavior for string literal ?

If no, what is definition we should use (can you give me some examples) ?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Hitokiri
  • 3,607
  • 1
  • 9
  • 29
  • 1
    Answers differ between C/ C++. In C both are OK. – chux - Reinstate Monica Apr 25 '20 at 16:16
  • i would like to know the answer both in C and C++ – Hitokiri Apr 25 '20 at 16:17
  • The _string literal_ is the same in both lines of code as the _string literal_ is just the `"string x"` part – chux - Reinstate Monica Apr 25 '20 at 16:19
  • 1 is invalid in modern C++, although you might find some compilers accept it with a warning. – john Apr 25 '20 at 16:23
  • it's not duplicate. And i updated the question – Hitokiri Apr 25 '20 at 16:29
  • 2
    Please ask two questions – one for C, one for C++. Dealing with both in a single answer is messy. Note that `strcpy(str1, "abc");` yields no warning but does invoke undefined behaviour; you're attempting to modify a string literal (and you're not allowed to do that), and doing so usually ends with a crash at run-time. The compiler does not have to identify undefined behaviour. The second `strcpy(str2, "abc")` fails to compile because you're attempting to modify data via a pointer that you've said points to constant data — that's not allowed either, and the compiler is required to report that. – Jonathan Leffler Apr 25 '20 at 16:44
  • Sorry about mixing two languages. I deleted the c++ tag. – Hitokiri Apr 25 '20 at 16:50
  • 1
    Hitokiri, you think there are 2 things here: string literal and const string literal. There are 3: 1) _string literals_ "string 1" and "string 2" 2) a pointer `char *str1` and 3) a pointer `const char *str2`. Compiler raises the warning just for `strcpy(str2,"abc");` because code passed a `const char *` to a `char *` of `strcpy(char *, ...`. The warning is nothing about _string literals_. – chux - Reinstate Monica Apr 25 '20 at 18:49
  • Thank you so much, i deleted the strcpy because i want to focus on the string literal. Thank to your comments, i understand the warning in strcpy function. – Hitokiri Apr 25 '20 at 22:32
  • The strcpy is just one example to prove 2 defintions are different, but thank to your answer, i think it’s bad example. Sorry for my fault. – Hitokiri Apr 25 '20 at 22:34

2 Answers2

1

If you need a mutable string you should use the following

char str1[]="string 1";

In C++ you cannot convert a string literal to non-const, in C you can, but this practice is not recommended.

Update.

In C++ you may do the following

char *str1 = (char *)"string 1" ; // (1)

But you must not use this pointer to change the value of the string.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
Sergey Strukov
  • 373
  • 3
  • 9
0

(1), is this an undefined behavior for string literal ?

This declaration

char *str1 = "string 1"; // (1)

is a valid declaration of a pointer to a string literal in C. Opposite to C++ in C string literals have types of non-constant character arrays.

However string literals are immutable in C as in C++. You may not change a string literal. Any attempt to change a string literal results in undefined behavior.

From the C Standard (6.4.5 String literals)

7 It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

It is preferable to declare pointers to string literals as it is required in C++ that is like

const char *str2 = "string 2"; // (2)

This makes your program more safer because the compiler will issue an error if you will try to pass a pointer to a string literal to a function the corresponding parameter of which is a pointer to non-constant char.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335