2

What is the difference between the line that does not compile and the line that does compile? The line that does not compile gives this warning: deprecated conversion from string constant to 'char*'

Also, I'm aware casting (char *) on the string being passed in to the function would solve the problem, but I would like to understand why that's even necessary when the 2nd line compiles just fine.

class Student {

  public:

    Student( char name[] ) {

    }

}

int main() {

  Student stud( "Kacy" ); //does not compile
  char name[20] = "Kacy";   //compiles just fine

}
Kacy Raye
  • 1,312
  • 1
  • 11
  • 14

3 Answers3

1

The char[] signature in the parameter is exactly the same as char*. In C++, it is illegal to convert a string constant char const* (the string "Kacy") to a char* because strings are immutable.

Your second example compiles because the name is an actual array. There is no change to char*.

As a solution, change your parameter to take a const string array:

Student(char const name[]);

which again is the same as

String(char const *name);

though you're better off using std::string:

#include <string>

class String
{
    public:
        String(std::string name);
};
David G
  • 94,763
  • 41
  • 167
  • 253
  • 'implicitly converted' is a bit inaccurate, IMHO. There's no conversion, they're literally the same. `char name[]` is just syntactic sugar for `char *name`. – Carl Norum Jun 19 '13 at 23:53
  • @CarlNorum Yeah, you're right. Twas thinking of something else. – David G Jun 19 '13 at 23:54
  • No problem, just wanted to clarify. – Carl Norum Jun 19 '13 at 23:54
  • Okay I think I understand what you're saying. Is the key difference between the two lines the fact that char name[] is a char* while char name[20] is an array, not a pointer? – Kacy Raye Jun 20 '13 at 00:02
  • @KacyRaye No, when used in a parameter list, an array type `T[N]` is functionally-equivalent to `T*`. That's not to say that they are equivalent in general. When using `T[N]` in, say, the main function, it represents an array, and `T*` represents a pointer to `T`. – David G Jun 20 '13 at 00:07
  • @KacyRaye Are you still having trouble understanding? I can explain further if you want me to! :-) – David G Jun 20 '13 at 00:16
  • Let me read through this one more time and I'll let you know. – Kacy Raye Jun 20 '13 at 00:28
  • @0x499602D2 After rereading your answer thoroughly, I feel like everything totally makes sense so thank you because I've been stuck on this concept for a while. I do have one question though. In the 2nd line that does compile, is the variable name considered a pointer? Since "Kacy" is a constant char pointer, does name point to the same memory address as the constant char pointer? – Kacy Raye Jun 20 '13 at 00:36
  • @KacyRaye No, `name` is an array. There is a difference between pointers and arrays. There is a great thread going over arrays [here](http://stackoverflow.com/questions/4810664/how-do-i-use-arrays-in-c). Scroll down to "Arrays are not pointers". – David G Jun 20 '13 at 00:43
  • Okay thanks. I didn't think so. I just wanted to make sure. Thank for you helping me get my fundamentals down :) – Kacy Raye Jun 20 '13 at 00:52
1

C++ string literals have type "array of n const char", which decays into const char * in your use case. The implicit conversion to char * (that is, discarding the const) you're trying is deprecated, so there's a warning. Change the type in the constructor's signature or make an explicit const-cast.

From the C++ standard:

An ordinary string literal has type "array of n const char" and static storage duration

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
0

The string

"Kacy"

is not an array of characters when the compiler produces the code. Instead, it will stash the string "Kacy" somewhere in memory, and produce a pointer to that place. So what you get is a const char * pointing at the string "Kacy\0".

If you change your constructor to:

 Student(const char *nmae)

you can use it both as:

 Student stud("Kacy");

and as this:

 char name[20] = "Kacy"; 
 Student stud2(name);

Note here that the compiler will generate code to FILL the array name with the characters in "Kacy", which is different from just usinv "Kacy" as an argument to the Student constructor.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • The string "Kacy" *is* an array. Which is why this works: `const char (&ref)[5] = "Kacy";` -- and this: `const char(*ptr)[5] = &"Kacy";` – Benjamin Lindley Jun 20 '13 at 01:09