difference between between these "char"s

I

icecrime

arnuld said:
On Mar 4, 12:12 pm, Ian Collins <[email protected]> wrote:
arnuld wrote:
Very very wrong!

char name[] = "hackers";

Is an automatic array of char, as such, it can be modified.

char *name = "hackers";

Is the incorrect way of writing

const char *name = "hackers";

A string literal should not be modified, to do so invokes undefined
behaviour and my cause your toilet to explode.


a "const char*" can easily be modified, see:


#include <iostream>

int main() {
int x = 7;
const char* author = "Stroustrup";

This means that the *pointee* is const, not the pointer.
std::cout << x
<< "\t"
<< author
<<"\n";

x = 100;
author = "Bjarne";

Here you're modifying the pointer, not the pointee. What the const is
keeping you from writing is for example:

author[0] = 'b'; // Illegal

However, is you had declared author as:

char * const author = "Stroustrup";

the pointer would've been const, but not the pointee :

author = "Bjarne"; // Illegal
author[0] = 'b'; // OK
 
A

arnuld

author is not a string literal in your example, it is a pointer
to one (actually two of them over your apps lifetime) in your case.

ok, it is a "pointer" to string literal and string literal *is* the
one who is a const.

You didn''t modify const. The const here, and where UB would come
in, is if you did something like:

*author = 'b';

to make his name lowercase.

what is "UB" ?

i did not get your "lowercase" behaviour. may you give an example with
an opposite case too.
 
G

Greg Comeau

arnuld said:
arnuld wrote:
Very very wrong!

char name[] = "hackers";

Is an automatic array of char, as such, it can be modified.

char *name = "hackers";

Is the incorrect way of writing

const char *name = "hackers";

A string literal should not be modified, to do so invokes undefined
behaviour and my cause your toilet to explode.


a "const char*" can easily be modified, see:


#include <iostream>

int main() {
int x = 7;
const char* author = "Stroustrup";

This means that the *pointee* is const, not the pointer.
std::cout << x
<< "\t"
<< author
<<"\n";

x = 100;
author = "Bjarne";

Here you're modifying the pointer, not the pointee. What the const is
keeping you from writing is for example:

author[0] = 'b'; // Illegal

However, is you had declared author as:

char * const author = "Stroustrup";

the pointer would've been const, but not the pointee :

author = "Bjarne"; // Illegal
author[0] = 'b'; // OK

Er, no, the last OK is still UB, which was Ian's point.

See, string literals have this odd duality to them:
the are const char [] (were not always) but have a conversion
(this was done as a compromise else almost every C++ (and C)
program woudl stop working) to char * so that legacy code can
keep working.
 
G

Greg Comeau

ok, it is a "pointer" to string literal and string literal *is* the
one who is a const.

Um, yes.
what is "UB" ?

Undefined behavior.
i did not get your "lowercase" behaviour. may you give an example with
an opposite case too.

I think you had the name as "Bjarne". Using *author = 'b'; is an
attempt to set it to be "bjarne" in memory. That's UB, so it
may or may not work on your system (actually it's probably ill-formed
these days too I'd have to check) and hence should be avoided.
 
A

arnuld

I think you had the name as "Bjarne". Using *author = 'b'; is an
attempt to set it to be "bjarne" in memory. That's UB, so it
may or may not work on your system (actually it's probably ill-formed
these days too I'd have to check) and hence should be avoided.

you want to say that:

char* name1 = "Bjarne"
const char* name2 = "Stroutrup"

name1 will get value 'B' and
name2 will get value 'S', which will be a const

rather than "Bjarne" and "Stroustrup" respecively.

after all of this, if you really think that i am STUPID. then i
request you to please explain it for me or point me to some other
place of information as it is really getting out of my head :-(

thanks

-- arnuld
http://arnuld.blogspot.com
 
A

Alf P. Steinbach

* arnuld:
you want to say that:

char* name1 = "Bjarne"
const char* name2 = "Stroutrup"

name1 will get value 'B' and
name2 will get value 'S', which will be a const

rather than "Bjarne" and "Stroustrup" respecively.

"*name1" refers to the single char that "name1" points to.

That's the first char in a string consisting of the characters 'B', 'j',
'a', 'r', 'n', 'e' and '\0', in succession in memory.

That storage must be regarded as read only because it's a string literal.

The pointer name1 is non-const, what it points to has to be treated as
read only.

Hence "*name1 = 'b';" would set the first character of the string to
'b', resulting in "bjarne" (plus terminating '\0'), except that
modifying a string literal is Undefined Behavior, so may not work.

after all of this, if you really think that i am STUPID. then i
request you to please explain it for me or point me to some other
place of information as it is really getting out of my head :-(

Hey, nobody said anything about stupidity.

We're trying to help.
 
A

arnuld

* arnuld:








"*name1" refers to the single char that "name1" points to.

oh..K, now i got it.

/name1/ and /*name1/ are same in meaning, pointing to the same "B" of
"Bjarne"

That's the first char in a string consisting of the characters 'B', 'j',
'a', 'r', 'n', 'e' and '\0', in succession in memory.

That storage must be regarded as read only because it's a string literal.

The pointer name1 is non-const, what it points to has to be treated as
read only.

Hence "*name1 = 'b';" would set the first character of the string to
'b', resulting in "bjarne" (plus terminating '\0'), except that
modifying a string literal is Undefined Behavior, so may not work.


Hey, nobody said anything about stupidity.

i know, but i felt that i am looking stupid.

We're trying to help.

of course....i am glad you said that

:)

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

a long time ago, as a USENET newbie, your words taught me how bad top-
posting is. keep them there, in your sig.

:)
 
G

Gavin Deane

oh..K, now i got it.

/name1/ and /*name1/ are same in meaning, pointing to the same "B" of
"Bjarne"

Not quite. name1 and *name1 are different. It's possible that Alf's
choice of the word "refers" above has confused you.

name1 _points to_ the 'B' of "Bjarne".

*name1 _is_ the 'B' of "Bjarne".
i know, but i felt that i am looking stupid.

Not really. Pointers and C-style strings are tricky to understand. But
it does make sense, and there will be a point where it suddenly clicks
and makes sense.

Gavin Deane
 
I

Ian Collins

arnuld said:
what does last sentence mean:

"a pointer to const to a pointer to non-const"
try compiling

const int n = 42;
const int* p = &n;
int* p1 = p;
 
I

Ian Collins

icecrime said:
Here you're modifying the pointer, not the pointee. What the const is
keeping you from writing is for example:

author[0] = 'b'; // Illegal

However, is you had declared author as:

char * const author = "Stroustrup";

the pointer would've been const, but not the pointee :

author = "Bjarne"; // Illegal
author[0] = 'b'; // OK
Oh look, there goes another exploding toilet!
 
I

icecrime

Here you're modifying the pointer, not the pointee. What the const is
keeping you from writing is for example:

author[0] = 'b'; // Illegal

However, is you had declared author as:

char * const author = "Stroustrup";

the pointer would've been const, but not the pointee :

author = "Bjarne"; // Illegal
author[0] = 'b'; // OK
Oh look, there goes another exploding toilet!

Sorry there :p I was too much into const correctness and ommited that it
is indeed falling into UB !
 
B

Bo Persson

arnuld said:
what does last sentence mean:

"a pointer to const to a pointer to non-const"


this pointer to a char notation:

char* x; or
char *x;

These are entirely equivalent, the placement of the * doesn't matter.

What I meant is that if you have a pointer to const, like

const int* ci;

and a pointer to non-const

int* p;

it is not allowed to assign ci to p, as this would allow us using p to
change what is really const.

p = ci; // NOT allowed


But, with char* you are allowed to do this anyway

char* x = "Hello";

even though this assigns a 'const char*' to a 'char*'. There is nothing to
understand here, and nothing Bjarne is proud of, it just the way it has
always been.

Please stay with std::string, and save this for much later! :)


to me, i do not think pointers are difficult than Templates. i do not
have any teacher/mentor who can teach me, except you folks. all of the
colleges here teach a language named VC++ & they do not agree that
"Linux is a good OS" and i am a UNIX man, that is the trouble.

But we have just seen that pointers ARE difficult, and that there are some
dark corners with very special rules. And that sometimes pointers and arrays
behave the same, and sometimes definitely not. This is the C part of C++,
that is not a good idea to try to learn first. It is not very useful,
really.


Bo Persson
 
G

Gavin Deane

ok, finally i got it:

char* author = "Bjarne"

will be implicitly converted to

const char* author = "Bjarne"

You've got that the wrong way round. The string literal "Bjarne" has
the type const char[] (array of const char). When you write

char* author = "Bjarne"

the implicit conversion is from const char[] (array of CONST char) to
char* (pointer to NON-CONST char). You've implicitly converted from
array to pointer and from const to non-const. Array to pointer is fine
- that implicit conversion happens all the time in C++. The awkward
bit that is peculiar to string literals is the implicit conversion
from const to non-const. That doesn't happen anywhere else in c++.
/author/ "points" to "B" of "Bjarne"
/*author/ "is" "B" of "Bjarne"

you can change where /author/ points to but that leads to UB.

No. Changing the *pointer* is fine. Changing *what it points to* leads
to UB.

char* author = "Bjarne";
author = "Stroustrup"; // Example 1. No problem
*author = 's'; // Example 2. UB

There are two separate string literals in that code snippet, "Bjarne"
and "Stroustrup". In example 1, all I am doing is taking author (which
is my pointer) and making it point to a different string literal. I am
not attempting to *modify* either string literal. Example 2 on the
other hand is an attempt to modify the first character of the string
literal "Stroustrup". I am attempting to change the character 'S' into
the character 's'. That leads to UB.
whereas with:

const int x = 8;
int* y;

doing /y = x/ will not work

right ?

Doing y = x will not work because y and x are not the same type -
nothing to do with const. x is an int and y is a pointer. What I think
you meant was

const int x = 8;
int* y;
y = &x;

The statement y = &x does not compile. &x is a pointer to CONST int
and y is a pointer to NON-CONST int. What you are seeing here is the
compiler preventing you from acquiring a pointer that could be used to
modify const data. This is the rule that has to be relaxed for string
literals (for the backwards compatibility reasons already discussed).

Gavin Deane
 
G

Geo

Yes, however, this is only true if you directly initialize it with a string
literal. That's a stupid special rule to make C++ more compatible with C
code written by sloppy programmers.

sloppy? why do you say that, 'const' is a relatively late addition to
the 'c' language, how could not using a non-existant construct be
considered sloppy ??
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top