c style strings

Hi guys this is probably a pretty trivial question but a question that is quite important non the less,anyway for best practice its obviously best to use std::string but std::string is implemented with c style strings so it's good to know whats going on behind the scenes of the string class,

anyway I made tho functions one that takes a const char* and one that takes a char array

for the first function both str (the const char*) and str2 (the char array) get accepted into the function and it prints out hello for both strings

and the second function will work if I remove the const before the char* in the first string

and in printStringTwos case it will also accept a char* even though technically it is not a char[]

so my question is are char str2[] and char* str the same thing? and same thing in memory? will they always work interchangeably?

also why can you use both of them when printString only accepts a const char* str



thanks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 void printString(const char* str){


    cout << str << endl;
}

void printStringTwo(char str[]){


  cout << str << endl;

}

int main()
{

     const char* str = "hello";
     char str2[] = {'h','e','l','l','o',0};
     char *str3 = "hello";

     printStringTwo(str3);
}

Last edited on
Line 19: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

The 'str' on line 17 is a pointer. It points to the first character of a string literal constant "hello" (which has a null char after the 'o' char). In other words it was initialized with an address of some memory somewhere. That memory may not be written to.


The 'str2' on line 18 is an array of characters that has 6 elements. It was initialized by copying the six characters that you listed within the {} initializer. The six bytes of memory that the 'str2' refers to are in stack memory, just like all variables with automatic storage duration. You can modify the elements of the array.


The 'str3' is a pointer just like the 'str', but not const. The compiler warns you, because you have given this pointer the address of literal constant.

Since str3 is not const, you could try to modify pointed to memory via this pointer, which would be undefined behaviour, because the pointed to memory is const.


The printString clearly takes a const pointer as its argument. A non-const pointer can be implicitly converted into const pointer. That is safe, because the function cannot modify the memory that the pointer points to.


You cannot implicitly convert a const pointer into non-const; to drop constness. You might be able to explicitly drop const in some situations.


The printStringTwo has argument type char []. That is an alternative syntax for char*. Functions do not take arrays as arguments. The array decays to pointer.

You can call it with an array. The caller has an array and the array knows its size. The function, however, reveices only a pointer (to first element of the array). The function does not know whether it was called with a pointer or an array, nor how many elements that array has.

The << is a function too. In both printString and printStringTwo the version of << that takes const char* will be used.
This is really a const correctness issue not about any perceived differences between the pointer and array notation in the function signature.

If you're using a properly configured compiler compiling to one of the current standards your code shouldn't compile. Line 19 should cause the following error:
main.cpp|19|error: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]|
*str3 should be a const char* or an array[].

so my question is are char str2[] and char* str2 the same thing? ... will they always work interchangeably?

No they are not always the same, it depends on context.

Basically with your function parameters char* and char[] are equivalent, the only difference is the const qualifier. Remember when calling a function an array decays to a pointer.

But there is a difference in main() between a pointer to char (str) and an array of char (str2).

also why can you use both of them when printString only accepts a const char* str

This is where the difference in const and non-const comes into play.

When you const qualified the pointer in printString() you told the compiler that you will not change the contents string so it is then safe to pass a const string into the function.

However if you don't const qualify the parameter the compiler can't assume that the contents of the string will not be modified.



The printStringTwo has argument type char []. That is an alternative syntax for char*. Functions do not take arrays as arguments. The array decays to pointer.


that actually makes sense,I think I recall reading that somewhere before


But there is a difference in main() between a pointer to char (str) and an array of char (str2).


This is where the difference in const and non-const comes into play.


but in main both are different right? str is a pointer to a string literal in read only memory and str2 is an array of chars right?

thanks keskiverto and jlb

Last edited on
but in main both are different right?

Yes, that's what I said in the first line above (you're missing the quote from your post between those two lines). The second line refers to that missing quote from your previous post.

also why can you use both of them when printString only accepts a const char* str



str is a pointer to a string literal

str is a pointer to a const string literal.

in read only memory

Possibly, but the where is an implementation detail. Remember not all systems have "read only memory".

and str2 is an array of chars right

Yes.



why can you use both of them when printString only accepts a const char* str

There is no "only" in that. The printString does not care what you have.

What the "const" on 'str' does is that printString promises to not modify the stuff that the str points to.
The printString will treat even non-const parameters like they will be const.


The printStringTwo accepts only non-const.
thanks guys makes sense now :)
Topic archived. No new replies allowed.