Re: assigning const char* to char*



Peithon <Peithon@xxxxxxxxxxxxxx> writes:
This is a very simple question but I couldn't find it in your FAQ.

I'm using VC++ and compiling a C program, using the /TC flag.

I've got a function for comparing two strings

int strspcmp(const char * s1, const char * s2)
{

char* pS1 = s1;
char* pS2 = s2;
...
...

}

As you can see, I assign the two const ptrs to some non-const ptrs to
do some ptr arithmetic,
like incrementing the ptrs to compare the strings.
But I'm getting warning C4090 complaining about the assignment.
I thought I was doing the standard thing for ptr arithmetic. What am I
doing wrong?
How do I get rid of the warning?

This has already been ably answered, but perhaps a simpler example
might make the point clearer. I think your point of confusion is that
"const char*" means "pointer to const char", not "const pointer to
char", but I'll explore other issues as well.

int main(void)
{
const char *ptr = "hello";
char *copy_of_ptr = ptr;
*ptr = 'H';
return 0;
}

The declaration "const char *ptr" doesn't make ptr const; it makes
what it points to const. Here I've initialized ptr to point to a
string literal, i.e., to an array of 6 characters 'h', 'e', 'l', 'l',
'o', '\0'. This array could be stored in read-only memory; attempting
to modify it could cause the program crash (it's undefined behavior).

The declaration of copy_of_ptr doesn't use the "const" keyword, which
means I'm allowed to modify either the pointer object itself *or* what
it points to. By "allowed to", I mean that the compiler won't
complain if I try to do it; it will go ahead and generate code to do
what I asked. It's up to me to make sure that I actually *can* modify
whatever I'm trying to modify. If I lie to the compiler, it may or
may not complain.

But in this case, I *tried* to lie to the compiler and it caught me at
it. I attempted to initialize a char* to the value of ptr. If I
could do this, it would allow me to (attempt to) modify whatever
copy_of_ptr points to. And that's exactly why the language forbids
assigning the value of ptr to copy_of_ptr (it's a constraint
violation, requiring a diagnostic). My error is caught during
compilation, when I attempt to copy the pointer, which is much better
than not catching it until run time, when I actually try to modify the
string.

If the language, and therefore the compiler, allowed me to copy the
value of ptr to copy_of_ptr, then it would also allow me to attempt to
modify the string that it points to (remember that it might be in
read-only memory), all without telling me that I've done something
dangerous. Fortunately, the rules of the language are such that I
can't get away with this particular error quite so easily. (It is
overly lax about string literals, but that's another story.)

If you want a pointer to const char, declare it as:

const char *ptr;

If you want a const pointer to char (you can't modify the pointer, but
you can modify what it points to):

char *const ptr;

And if you want both the pointer *and* what it points to be read-only:

const char *const p;

The placement of the "const" keyword is tricky. If you can find a
program called "cdecl", it can help you with this kind of thing; I
used it to confirm these declarations.

% cdecl
Type `help' or `?' for help
cdecl> declare p as const pointer to char
char * const p
cdecl> declare p as const pointer to const char
const char * const p
cdecl> explain const char *p
declare p as pointer to const char
cdecl>

One thing to watch out for: cdecl treats "ptr" as a synonym for
"pointer", so if you tell it "declare ptr as pointer to const char" it
will report a syntax error.

--
Keith Thompson (The_Other_Keith) kst-u@xxxxxxx <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
.



Relevant Pages

  • Sun Studio 10 C++ compiler ignoring the const char* operator. Bug or feature?
    ... with Sun Studio 10 or higher. ... Take aany class with overloaded const char*() and char*operators. ... The compiler does not produce any warnings. ...
    (comp.unix.solaris)
  • Re: dh, the daemon helper
    ... some type is a special case, while const ordinarily binds to the ... ie char const * is a pointer to a constant ... no point in returning memory to the malloc heap. ... 2004 is the UNIX standard. ...
    (comp.unix.programmer)
  • Re: Whats the deal with const?
    ... will inevitably occur as one tries to compile and the compiler gripes ... remove the const keyword, and this might mean painstakingly removing it ... void print_first_5(char *x) ... printf(buf); ...
    (comp.lang.c)
  • Re: please help with mysterious error....
    ... declared two places in the same header-file so it seems that if there is only 1 place were the char* argument isn't const, ... produce arrays of plain `char', ... It can be argued that the switch makes the compiler non-conforming because as you note the standard says string literals are arrays of char, ...
    (comp.lang.c)
  • Re: dh, the daemon helper
    ... some type is a special case, while const ordinarily binds to the ... ie char const * is a pointer to a constant ... since this is the way UNIX(*) processes work. ...
    (comp.unix.programmer)