-3

I have the following code:

void uppercase(char *sir)
{

for(int i=0;i<strlen(sir);i++)
{

 sir[i]=(char)toupper(sir[i]);
}
} 


int _tmain(int argc, _TCHAR* argv[])
{

//char  lower[]="u forgot the funny"; this works
//char  *lower="u forgot the funny";  this gives me a runtime error

uppercase(lower);

cout<<lower<<"\n\n";

system("PAUSE");

return 0;
}

I have noted that if I run with the char vector it works. When I try to run with the second method it generates a runtime error. I would like to know the reason for this behaviour please.

dragosb
  • 607
  • 8
  • 25
  • A real C++ compiler shouldn't even *compile* the second case. – Kerrek SB Oct 18 '13 at 19:57
  • @KerrekSB: In C++11, I would agree. But in C++03, I believe this will compile and be well-defined -- which is not to say what the programmer might expect! – John Dibling Oct 18 '13 at 20:00
  • @KerrekSB clang on osx just givves a warning `conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]` – SheetJS Oct 18 '13 at 20:00
  • Turn your warnings on and make the code compile with no warnings. Warnings are logical errors in your thinking. – Martin York Oct 18 '13 at 20:06
  • @JohnDibling: Oh right, I forget that this used to be different. I mean, the literal has always been a const char array, right? It's only the conversion that used to be allowed? – Kerrek SB Oct 18 '13 at 20:06
  • @KerrekSB: Correct. Even tho the pointer is not `const`, modifying the values pointed to would evoke Undefined Behavior -- but the compiler would allow the initialization of the pointer. – John Dibling Oct 18 '13 at 20:25

2 Answers2

2

You cannot modify string literals; doing so (as in your second case) is undefined behaviour.

char x[] = "foo";

creates a character array containing the characters f,o,o,\0. It's basically a mutable copy of the string.

char *x = "foo";

creates a string pointer pointing to the "foo" string literal. The literal may live in some read-only memory, in the program memory, or in a constant pool. Writing to it is undefined behaviour. Also, not that the type of a string literal is always const char[], so assigning it to a char * is violating const-correctness.

nneonneo
  • 171,345
  • 36
  • 312
  • 383
  • +1 but note: the `char*` example will no longer even compile under C++11. – John Dibling Oct 18 '13 at 20:01
  • As nneonneo said, the latter don't work because you can't convert const string literal to non-const char *. That being said, adding 'const' before 'char *x = "foo";' will work. – nomann Oct 18 '13 at 20:13
1

The former creates a character array which can be mutated, the latter is a pointer to fixed memory (which cannot be manipulated)

SheetJS
  • 22,470
  • 12
  • 65
  • 75