0

My bad!!I had assumed that the following excerpt from a notorious yet wildly popular book is totally valid C.But only today I was pointed out that it's ridden with UB (though I am yet to find how come it's so).Hence here's that particular section from the book.You will be doing me and many other "victims" like me a great favor if you can point out in a numbered manner what is wrong or UB with each particular statement,and the appropriate corrections for those.

char *p = "Hello" ;  /* pointer is variable, so is string */ 
*p = 'M' ;  /* works */ 
p = "Bye" ;  /* works */ 


const char *q = "Hello" ;  /* string is fixed pointer is not */ 
*q = 'M' ;  /* error */ 
q = "Bye" ;  /* works */ 


char const *s = "Hello" ;  /* string is fixed pointer is not */ 
*s = 'M' ;  /* error */ 
s = "Bye" ;  /* works */ 


char * const t = "Hello" ;  /* pointer is fixed string is not */ 
*t = 'M' ;  /* works */    
t = "Bye" ;  /* error */ 


const char * const u = "Hello" ;  /* string is fixed so is pointer */ 
*u = 'M' ;  /* error */ 
u = "Bye" ;  /* error */ 
Rüppell's Vulture
  • 3,583
  • 7
  • 35
  • 49
  • 1
    `char *p` should point to a non-const string. string literals are constants. – Elazar Apr 28 '13 at 18:28
  • 1
    The `q` and `s` cases above are identical. `const char *` and `char const *` are the same type. – Mat Apr 28 '13 at 18:28
  • @mat Do me & others like me a real favor.Take a minute to post a detailed answer. – Rüppell's Vulture Apr 28 '13 at 18:28
  • The only problems above are when you attempt to write to the string literal (cases `p` and `t`). This has been explained hundreds of times already. All the other cases have const in the right places (or more) so the compiler will warn you. – Mat Apr 28 '13 at 18:34

2 Answers2

1
char *p = "Hello"

"Hello" is a string literal placed in implementation read only memory and modifying it in any possible way is an UB. Irrespective of where you put the const qualifier any attempt to modify the string literal is a UB. The correct way to represent this in C++ is:

const char *p = "Hello";

char *p = "Hello" ;

Pointer can be reseated but the string should not be modified.

const char *q = "Hello" ;
char const *s = "Hello" ;

The correct way to represent a pointer pointing to string literal in C++. The pointer can be reseated but the string should not be modified.

char * const t = "Hello" ;

Pointer cannot be reseated and the string should not be modified.

const char * const u = "Hello" ;

Pointer is constant so is the string.

Any attempt to modify the string in any of these is an UB.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • Since the question is tagged C and is not tagged C++, shouldn't this answer describe the situation in C, as opposed to what is correct in C++? (the traditional answer to this is that C and C++ are almost the same for the C subset of C++. Well, if they are the same, one might as well explain the situation in C. Plus this particular question involves string literals and character literals, both of which have different types in C and in C++) – Pascal Cuoq Apr 29 '13 at 08:23
  • @PascalCuoq I am about to drill whatever Alok said into my head.If you feel anything about what he said is different for C,can you kindly put that in an answer? – Rüppell's Vulture May 13 '13 at 12:38
1

These two cases are undefined behavior:

char *p = "Hello" ;
*p = 'M' ;  // Undefined behavior: trying to modify a string literal.


char * const t = "Hello" ;
*t = 'M' ;  // Undefined behavior: trying to modify a string literal.
Vaughn Cato
  • 63,448
  • 5
  • 82
  • 132