String Constant absent in C++

Discussion in 'C Programming' started by karthikbalaguru, Sep 2, 2007.

  1. Hi,
    String constant being modifiable in C++ but, not modifiable in C.
    that is,
    In C++, the following example output will be "Mplusplus"
    char *str1 = "Cplusplus";
    *str1 = 'M';
    In C, the above example will produce an error as we are trying to
    modify a constant.

    So, str1 is not a string constant in C++.
    Does it mean that string constant concept is absent in C++ ?

    Thx in advans,
    Karthik Balaguru
     
    karthikbalaguru, Sep 2, 2007
    #1
    1. Advertising

  2. karthikbalaguru wrote:
    > Hi,
    > String constant being modifiable in C++ but, not modifiable in C.
    > that is,
    > In C++, the following example output will be "Mplusplus"
    > char *str1 = "Cplusplus";
    > *str1 = 'M';
    > In C, the above example will produce an error as we are trying to
    > modify a constant.
    >
    > So, str1 is not a string constant in C++.
    > Does it mean that string constant concept is absent in C++ ?


    This is one of those really bad decisions by the C++ committee.

    String literals are of type const char [], however, for reasons of
    wisdom beyond my grasp, the standard allows sting literals (and only
    string literals) to be assigned to a "char * ptr" by implicitly const
    casting. More than likely, trying to modify the string literal will
    cause your program to segv. Go figure.
     
    Gianni Mariani, Sep 2, 2007
    #2
    1. Advertising

  3. karthikbalaguru

    peter koch Guest

    On 2 Sep., 12:36, karthikbalaguru <> wrote:
    > Hi,
    > String constant being modifiable in C++ but, not modifiable in C.
    > that is,
    > In C++, the following example output will be "Mplusplus"
    > char *str1 = "Cplusplus";
    > *str1 = 'M';
    > In C, the above example will produce an error as we are trying to
    > modify a constant.
    >


    This is not correct. In both C and C++ str1 is a constant pointer to
    char. An attempt to modify it causes undefined behaviour, which could
    result in anything - including the behaviours mentioned above. In
    practice, the behaviour depends on where the compiler decides to put
    its string constants.
    The correct way to initialise such a pointer is to remember the const:
    eg.

    char const* str1 = "Cplusplus".

    char* is a special case and the only place where you can leave out the
    const. It was made special in order to faciliate porting old C and C++
    code.

    > So, str1 is not a string constant in C++.


    So yes it is...

    > Does it mean that string constant concept is absent in C++ ?

    .... and no it is not.

    /Peter
     
    peter koch, Sep 2, 2007
    #3
  4. karthikbalaguru

    Ian Collins Guest

    karthikbalaguru wrote:
    > Hi,
    > String constant being modifiable in C++ but, not modifiable in C.
    > that is,
    > In C++, the following example output will be "Mplusplus"
    > char *str1 = "Cplusplus";
    > *str1 = 'M';
    > In C, the above example will produce an error as we are trying to
    > modify a constant.
    >

    No it won't, because str1 isn't a const.

    Some C++ compilers will warn that a string literal is being assigned to
    a char*

    > So, str1 is not a string constant in C++.


    Correct, nor is it one in C. It may point to a string literal, but it
    isn't declared const.

    > Does it mean that string constant concept is absent in C++ ?
    >

    Of course not.

    cat x.c

    int main() {
    const char *str1 = "Cplusplus";
    *str1 = 'M';
    }

    gcc -Wall -ansi -pedantic x.c
    /tmp/x.c:3: error: assignment of read-only location

    g++ -Wall -ansi -pedantic x.c
    /tmp/x.c:3: error: assignment of read-only location

    --
    Ian Collins.
     
    Ian Collins, Sep 2, 2007
    #4
  5. karthikbalaguru

    Pete Becker Guest

    On 2007-09-02 06:43:07 -0400, Gianni Mariani <> said:

    > karthikbalaguru wrote:
    >> Hi,
    >> String constant being modifiable in C++ but, not modifiable in C.
    >> that is,
    >> In C++, the following example output will be "Mplusplus"
    >> char *str1 = "Cplusplus";
    >> *str1 = 'M';
    >> In C, the above example will produce an error as we are trying to
    >> modify a constant.
    >>
    >> So, str1 is not a string constant in C++.
    >> Does it mean that string constant concept is absent in C++ ?

    >
    > This is one of those really bad decisions by the C++ committee.
    >
    > String literals are of type const char [], however, for reasons of
    > wisdom beyond my grasp, the standard allows sting literals (and only
    > string literals) to be assigned to a "char * ptr" by implicitly const
    > casting. More than likely, trying to modify the string literal will
    > cause your program to segv. Go figure.


    The reason is that historically, C-style strings were not always
    constant, and there was code that relied on this. The rule in C++ is
    that the type of a string literal is array-of-const-char. The literal
    can be converted into a pointer-to-char, but that you write to it at
    your peril. That preserves the status quo. The conversion is
    deprecated, so portable code should not rely on it.

    --
    Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
    Standard C++ Library Extensions: a Tutorial and Reference
    (www.petebecker.com/tr1book)
     
    Pete Becker, Sep 2, 2007
    #5
  6. Pete Becker wrote:
    > On 2007-09-02 06:43:07 -0400, Gianni Mariani <> said:

    ....
    > The reason is that historically, C-style strings were not always
    > constant, and there was code that relied on this. The rule in C++ is
    > that the type of a string literal is array-of-const-char. The literal
    > can be converted into a pointer-to-char, but that you write to it at
    > your peril. That preserves the status quo. The conversion is deprecated,
    > so portable code should not rely on it.


    Knowing what you know today, would the reason you gave here be a worthy
    reason to make the same decision again or if you could go back in time,
    would you vote to not allow string literals to be assign to a char *?
     
    Gianni Mariani, Sep 2, 2007
    #6
  7. karthikbalaguru

    Jerry Coffin Guest

    In article <>,
    says...
    > Hi,
    > String constant being modifiable in C++ but, not modifiable in C.
    > that is,
    > In C++, the following example output will be "Mplusplus"
    > char *str1 = "Cplusplus";
    > *str1 = 'M';
    > In C, the above example will produce an error as we are trying to
    > modify a constant.


    There's really no difference between the languages in this respect. In
    either case, attempting to write to the string constant produces
    undefined behavior. That means anything can happen in either case. Any
    difference you see is an artifact of the compiler(s) you're using, not
    anything mandated by the definitions of the languages -- in fact, in
    both cases, the language definitions specifically do NOT mandate
    anything.

    > So, str1 is not a string constant in C++.
    > Does it mean that string constant concept is absent in C++ ?


    No. Your code has undefined behavior, so it means essentialy nothing
    about either C or C++.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
     
    Jerry Coffin, Sep 2, 2007
    #7
  8. karthikbalaguru

    Jerry Coffin Guest

    In article <46dab1c0$0$28516$5a62ac22@per-qv1-newsreader-
    01.iinet.net.au>, says...

    [ ... ]

    > Knowing what you know today, would the reason you gave here be a worthy
    > reason to make the same decision again or if you could go back in time,
    > would you vote to not allow string literals to be assign to a char *?


    I can't speak for Pete, but _I_ think the decision was completely
    reasonable. C++ has always been designed with the explicit goal of
    remaining compatible with most C code, even when it forced a comprimise
    in the language in terms of safety, elegance, etc.

    You can find quite a few languages that are more or less contemperaneous
    with C++ that are (at least arguably) safer and more elegant -- but none
    of them has anywhere close to the acceptance and user base of C++. The
    ability to assign a string literal to a non-const char * has been
    deprecated so at some point in the future it may disappear -- but if it
    had been eliminated early on, it would have also eliminated the ability
    to compile most C code as C++, and in the process would probably have
    nearly killed C++.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
     
    Jerry Coffin, Sep 2, 2007
    #8
  9. "Gianni Mariani" <> wrote in message
    news:46da93bf$0$28513$...

    > This is one of those really bad decisions by the C++ committee.


    > String literals are of type const char [], however, for reasons of wisdom
    > beyond my grasp, the standard allows sting literals (and only string
    > literals) to be assigned to a "char * ptr" by implicitly const casting.


    C++ does that because C allows it too: In C, you can convert const char * to
    char * without a cast.
     
    Andrew Koenig, Sep 2, 2007
    #9
  10. Andrew Koenig wrote:
    > "Gianni Mariani" <> wrote in message
    > news:46da93bf$0$28513$...
    >
    >> This is one of those really bad decisions by the C++ committee.

    >
    >> String literals are of type const char [], however, for reasons of wisdom
    >> beyond my grasp, the standard allows sting literals (and only string
    >> literals) to be assigned to a "char * ptr" by implicitly const casting.

    >
    > C++ does that because C allows it too: In C, you can convert const char *
    > to char * without a cast.


    In C, you cannot convert a const char * to char * without a cast. In C, you
    can assign a string literal to a char * without a cast, because string
    literals have type array of char.
     
    Harald van =?UTF-8?B?RMSzaw==?=, Sep 2, 2007
    #10
  11. karthikbalaguru

    Pete Becker Guest

    On 2007-09-02 08:51:08 -0400, Gianni Mariani <> said:

    > Pete Becker wrote:
    >> On 2007-09-02 06:43:07 -0400, Gianni Mariani <> said:

    > ...
    >> The reason is that historically, C-style strings were not always
    >> constant, and there was code that relied on this. The rule in C++ is
    >> that the type of a string literal is array-of-const-char. The literal
    >> can be converted into a pointer-to-char, but that you write to it at
    >> your peril. That preserves the status quo. The conversion is
    >> deprecated, so portable code should not rely on it.

    >
    > Knowing what you know today, would the reason you gave here be a worthy
    > reason to make the same decision again or if you could go back in time,
    > would you vote to not allow string literals to be assign to a char *?


    No. There is quite a bit of existing code that does this, and having to
    retrofit const modifiers, even for the vast majority of cases where the
    code doesn't modify the pointee, would be a pointless exercise. If you
    don't want to use the conversion, don't use it. If you want to enforce
    not using it in your code, get a lint tool or turn on a compiler
    warning.

    --
    Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
    Standard C++ Library Extensions: a Tutorial and Reference
    (www.petebecker.com/tr1book)
     
    Pete Becker, Sep 2, 2007
    #11
  12. peter koch <> writes:
    > On 2 Sep., 12:36, karthikbalaguru <> wrote:
    >> Hi,
    >> String constant being modifiable in C++ but, not modifiable in C.
    >> that is,
    >> In C++, the following example output will be "Mplusplus"
    >> char *str1 = "Cplusplus";
    >> *str1 = 'M';
    >> In C, the above example will produce an error as we are trying to
    >> modify a constant.

    >
    > This is not correct. In both C and C++ str1 is a constant pointer to
    > char. An attempt to modify it causes undefined behaviour, which could
    > result in anything - including the behaviours mentioned above. In
    > practice, the behaviour depends on where the compiler decides to put
    > its string constants.


    That's not correct either. In C, a string literal is of type array of
    char. Attempting to modify a string literal invokes undefined
    behavior, not because it's const (it isn't), but because the C
    standard explicitly says that attempting to modify a string literal
    invokes undefined behavior.

    > The correct way to initialise such a pointer is to remember the const:
    > eg.
    >
    > char const* str1 = "Cplusplus".


    Agreed.

    > char* is a special case and the only place where you can leave out the
    > const. It was made special in order to faciliate porting old C and C++
    > code.
    >
    >> So, str1 is not a string constant in C++.

    >
    > So yes it is...


    Well, no, str1 is an object of type char*.

    [...]

    --
    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, Sep 2, 2007
    #12
  13. Pete Becker <> writes:
    [...]
    > The reason is that historically, C-style strings were not always
    > constant, and there was code that relied on this. The rule in C++ is
    > that the type of a string literal is array-of-const-char. The literal
    > can be converted into a pointer-to-char, but that you write to it at
    > your peril. That preserves the status quo. The conversion is


    There's a little more to the historical background than that. Early C
    didn't have the 'const' keyword, so if you wanted to pass a string
    literal to a function, that function had to take a 'char*' argument:

    func(str)
    char *str;
    {
    /* code that doesn't modify the string */
    }

    ...

    func("Hello, world");

    If ANSI C had made string literals const, such code (which was
    perfectly valid when it was written) would have been broken, and the
    transition from pre-ANSI to ANSI would have been more difficult.

    --
    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, Sep 2, 2007
    #13
  14. Pete Becker wrote:
    > On 2007-09-02 08:51:08 -0400, Gianni Mariani <> said:

    ....
    >> Knowing what you know today, would the reason you gave here be a
    >> worthy reason to make the same decision again or if you could go back
    >> in time, would you vote to not allow string literals to be assign to a
    >> char *?

    >
    > No.


    ?

    > ... There is quite a bit of existing code that does this, and having to
    > retrofit const modifiers, even for the vast majority of cases where the
    > code doesn't modify the pointee, would be a pointless exercise. If you
    > don't want to use the conversion, don't use it. If you want to enforce
    > not using it in your code, get a lint tool or turn on a compiler warning.


    There are plenty of other reasons for code to have been modified so I
    don't see how the pre-existing code argument supports your position.
    Also, instead of mandating this rule to be standard, you could have left
    it up to the compiler supplier to provide a "compatability" flag as many
    do for some reason or another for other issues.

    I think we'll just have to agree to disagree.
     
    Gianni Mariani, Sep 2, 2007
    #14
  15. karthikbalaguru

    Tobias Guest

    Hello,
    I have to use Visual Studio 2005 at work:-(. Think, M$VC8 is the
    associated compiler.
    For me auto_ptr of M$ was broken. Some static cast instead of the
    right dynamic one.
    Makes polymorphic use impossible. Maybe, this is fixed in your version
    of M$VC.
    Best regards,
    Tobias
     
    Tobias, Sep 3, 2007
    #15
  16. On Sep 2, 3:54 pm, Ian Collins <> wrote:
    > karthikbalaguru wrote:
    > > Hi,
    > > String constant being modifiable in C++ but, not modifiable in C.
    > > that is,
    > > In C++, the following example output will be "Mplusplus"
    > > char *str1 = "Cplusplus";
    > > *str1 = 'M';
    > > In C, the above example will produce an error as we are trying to
    > > modify a constant.

    >
    > No it won't, because str1 isn't a const.
    >
    > Some C++ compilers will warn that a string literal is being assigned to
    > a char*
    >
    > > So, str1 is not a string constant in C++.

    >
    > Correct, nor is it one in C. It may point to a string literal, but it
    > isn't declared const.
    >
    > > Does it mean that string constant concept is absent in C++ ?

    >
    > Of course not.
    >
    > cat x.c
    >
    > int main() {
    > const char *str1 = "Cplusplus";
    > *str1 = 'M';
    >
    > }
    >
    > gcc -Wall -ansi -pedantic x.c
    > /tmp/x.c:3: error: assignment of read-only location
    >
    > g++ -Wall -ansi -pedantic x.c
    > /tmp/x.c:3: error: assignment of read-only location
    >
    > --
    > Ian Collins.


    Thats interesting. Thx Ian.

    Further from Peter's reply. I conclude.
    In both C and C++ str1 is a constant pointer to char. An attempt to
    modify it causes undefined
    behaviour. The correct way to initialise such a pointer is to remember
    the const:
    eg.

    char const* str1 = "Cplusplus".

    char* is a special case and the only place where you can leave out the
    const. It was made special in
    order to faciliate porting old C and C++ code.

    Thx,
    Karthik Balaguru
     
    karthikbalaguru, Sep 4, 2007
    #16
  17. karthikbalaguru

    James Kanze Guest

    On Sep 2, 2:51 pm, Gianni Mariani <> wrote:
    > Pete Becker wrote:
    > > On 2007-09-02 06:43:07 -0400, Gianni Mariani <> said:

    > ...
    > > The reason is that historically, C-style strings were not always
    > > constant, and there was code that relied on this. The rule in C++ is
    > > that the type of a string literal is array-of-const-char. The literal
    > > can be converted into a pointer-to-char, but that you write to it at
    > > your peril. That preserves the status quo. The conversion is deprecated,
    > > so portable code should not rely on it.


    > Knowing what you know today, would the reason you gave here be a worthy
    > reason to make the same decision again or if you could go back in time,
    > would you vote to not allow string literals to be assign to a char *?


    The decision was the only possible one. Anything else would
    have broken too much code. It would have been absolutely
    unacceptable to have made something like:
    char* p = "abc" ;
    to have been illegal. The only choice was in the mechansim
    which is used to allow it. The C committee simply made the type
    of "abc" char[4], and said that despite a non-const type, it was
    undefined behavior to attempt to modify it. The C++ committee
    went a step further, and said that "abc" had type char const[4],
    but introduced a very special conversion to allow the above to
    work.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Sep 4, 2007
    #17
  18. karthikbalaguru

    James Kanze Guest

    On Sep 2, 12:54 pm, Ian Collins <> wrote:
    > karthikbalaguru wrote:


    > > String constant being modifiable in C++ but, not modifiable in C.
    > > that is,
    > > In C++, the following example output will be "Mplusplus"
    > > char *str1 = "Cplusplus";
    > > *str1 = 'M';
    > > In C, the above example will produce an error as we are trying to
    > > modify a constant.


    > No it won't, because str1 isn't a const.


    It might, or it might not. The expression "*str1 = 'M'"
    attempts to modify a character in a string literal. In both C
    and C++, this is undefined behavior (albeit for slightly
    different reasons). Historically:

    1. In K&R C, there was no const. In addition, K&R guaranteed
    that 1) all string literals occupied distinct storage, and
    2) that they could be modified. This last ability was
    considered a defect by many, so...

    2. The C standards committee declared that it was undefined
    behavior to attempt such a modification (an implementation
    could put the literal in write-only memory), and that it was
    unspecified whether two identical string literals occupied
    distinct memory or not.

    The C standards committee also adopted the const keyword
    from C++, but decided not to apply it to the type (char[])
    of a string literal.

    3. In C++, const plays a much larger role than in C. (E.g. it
    is involved in function overload resolution.) For this
    reason, the C++ committee decided that the type of a string
    literal must be char const[], and not simply char[]. Still,
    it was quite obvious that they couldn't responsibly break
    things like ``char* p = "abc" ;'', so they introduced a
    special conversion, which only applies in specific cases
    (and which could easily cause a compiler warning when used).

    For historical reasons, most C++ compilers still have an option
    to treat string literals as they were treated in K&R C: as
    writable objects, with guaranteed separate data for each
    literal. And even today, this is the default for some
    compilers (Sun CC, for example).

    > Some C++ compilers will warn that a string literal is being assigned to
    > a char*


    I think that the committee really wanted to encourage such
    warnings.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Sep 4, 2007
    #18
  19. karthikbalaguru

    red floyd Guest

    James Kanze wrote:

    >
    > It might, or it might not. The expression "*str1 = 'M'"
    > attempts to modify a character in a string literal. In both C
    > and C++, this is undefined behavior (albeit for slightly
    > different reasons). Historically:


    > 2. The C standards committee declared that it was undefined
    > behavior to attempt such a modification (an implementation
    > could put the literal in write-only memory),


    Now *THAT* would be an interesting decision by the implementor. :)
    I know you meant to say "read-only memory".
     
    red floyd, Sep 4, 2007
    #19
  20. karthikbalaguru

    Old Wolf Guest

    karthikbalaguru wrote:
    > Further from Peter's reply. I conclude.
    > In both C and C++ str1 is a constant pointer to char.


    Peter's reply was wrong. str1 is a non-const pointer to
    char, in both languages. A constant pointer to char
    would look like:
    char *const str1

    > An attempt to
    > modify it causes undefined
    > behaviour. The correct way to initialise such a pointer is to remember
    > the const:
    > eg.
    >
    > char const* str1 = "Cplusplus".
    >
    > char* is a special case and the only place where you can leave out the
    > const. It was made special in
    > order to faciliate porting old C and C++ code.
    >
    > Thx,
    > Karthik Balaguru


    The above text has been copied verbatim from peter koch's
    post. You should use some kind of quote marking
    mechanism when you do this, otherwise it looks
    like you are plagiarizing somebody else's ideas.
     
    Old Wolf, Sep 5, 2007
    #20
    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. Stanimir Stamenkov
    Replies:
    3
    Views:
    1,264
    Stanimir Stamenkov
    Apr 25, 2005
  2. Replies:
    0
    Views:
    320
  3. shaanxxx

    Waring for string is absent.

    shaanxxx, Aug 26, 2006, in forum: C Programming
    Replies:
    5
    Views:
    393
    Simon Biber
    Aug 26, 2006
  4. Guest
    Replies:
    0
    Views:
    345
    Guest
    Jul 9, 2007
  5. karthikbalaguru

    String Constant absent in C++

    karthikbalaguru, Sep 2, 2007, in forum: C++
    Replies:
    30
    Views:
    993
    Charles Richmond
    Sep 7, 2007
Loading...

Share This Page