assigning const char* to char*

Discussion in 'C Programming' started by Peithon, Jun 1, 2007.

  1. Peithon

    Peithon Guest

    Hi,

    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?
    Peithon, Jun 1, 2007
    #1
    1. Advertising

  2. Peithon said:

    > Hi,
    >
    > 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)


    Although it has nothing to do with your question, I should perhaps point
    out that the name strspcmp is reserved. str_spcmp is not, however.

    > {
    >
    > 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.


    You don't need to do that, and in fact it's a bad idea. The const char *
    syntax doesn't mean "this pointer can't change". It means "you can't
    write through this pointer". ++s1 is fine. *s1 = '\0', however, is not.
    And since you don't want to do that anyway, I suggest that you use
    const char * - in which case pS1 and pS2 become redundant; you might as
    well use s1 and s2 directly. (Remember that C is pass-by-value, so ++s1
    only changes your local copy of the pointer, not the value of the
    pointer passed by the caller.)

    <snip>

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
    Richard Heathfield, Jun 1, 2007
    #2
    1. Advertising

  3. Peithon

    Richard Guest

    Peithon <> writes:

    > Hi,
    >
    > 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?


    For a start you post the warning you are getting :-;
    Richard, Jun 1, 2007
    #3
  4. Peithon <> writes:

    > Hi,
    >
    > 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)


    You are invading the implementation's name space.

    > {
    >
    > char* pS1 = s1;
    > char* pS2 = s2;
    > ...
    > ...
    >
    > }
    >
    > As you can see, I assign the two const ptrs to some non-const ptrs


    The pointers are not const. They point to const char. Subtle but
    important distinction.

    > to do some ptr arithmetic,


    Odd. You can do arithmetic on const char * as well and you would not
    get the warnings.

    > like incrementing the ptrs to compare the strings.
    > But I'm getting warning C4090 complaining about the assignment.


    As you must. It requires a diagnostic.

    > I thought I was doing the standard thing for ptr arithmetic. What am I
    > doing wrong?
    > How do I get rid of the warning?


    Just to the pointer arithmetic on the const char *s1 and s2.

    --
    Ben.
    Ben Bacarisse, Jun 1, 2007
    #4
  5. Peithon

    Peithon Guest

    On 1 Jun, 18:47, Ben Bacarisse <> wrote:
    > Peithon <> writes:
    > > Hi,

    >
    > > 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)

    >
    > You are invading the implementation's name space.
    >
    > > {

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

    >
    > > }

    >
    > > As you can see, I assign the two const ptrs to some non-const ptrs

    >
    > The pointers are not const. They point to const char. Subtle but
    > important distinction.
    >
    > > to do some ptr arithmetic,

    >
    > Odd. You can do arithmetic on const char * as well and you would not
    > get the warnings.
    >
    > > like incrementing the ptrs to compare the strings.
    > > But I'm getting warning C4090 complaining about the assignment.

    >
    > As you must. It requires a diagnostic.
    >
    > > I thought I was doing the standard thing for ptr arithmetic. What am I
    > > doing wrong?
    > > How do I get rid of the warning?

    >
    > Just to the pointer arithmetic on the const char *s1 and s2.
    >
    > --
    > Ben.


    Thanks, I didn't see the distinction between const char * and char *
    const.
    Much appreciated.
    Peithon, Jun 1, 2007
    #5
  6. Peithon wrote:
    > Hi,
    >
    > 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?
    >


    typing

    const char *a;

    means you have a pointer to a char and are not allowed to modify what it
    points to (but you are allowed to modify the pointer).
    that means

    char b;

    a="hello";
    a++;
    b=*a;

    is valid code, but not:
    a=&b;
    *a=' '; /* this line is not valid */

    since this is valid:

    char *c;
    c=&b;
    *c=' ';

    but modifying something pointed to by a const pointer is not is this
    also not valid:

    a=&b;
    c=a; /* gives the warning you mentioned */
    *c=' '; /* this statement is still valid */
    Johan Bengtsson, Jun 1, 2007
    #6
  7. Peithon <> 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) <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"
    Keith Thompson, Jun 1, 2007
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Thomas Matthews
    Replies:
    5
    Views:
    2,414
    tom_usenet
    Aug 2, 2004
  2. Replies:
    24
    Views:
    831
    Netocrat
    Oct 30, 2005
  3. lovecreatesbeauty
    Replies:
    1
    Views:
    1,046
    Ian Collins
    May 9, 2006
  4. Javier
    Replies:
    2
    Views:
    561
    James Kanze
    Sep 4, 2007
  5. thomas
    Replies:
    8
    Views:
    1,298
    Victor Bazarov
    Aug 21, 2012
Loading...

Share This Page