No compile-time error on modifying string literals

Discussion in 'C++' started by Victor Bazarov, Feb 14, 2005.

  1. Ney André de Mello Zunino wrote:
    > The following is a summary of what I have understood from reading
    > Stroustrup's TCPL 3rd Edition's discourse on "string literals" (5.2.2).
    >
    > String literals are of type const char[n], where n is the length of the
    > literal plus one. However, for compatibility reasons, assignment of such
    > a literal to a non-const char* is allowed, e.g.:
    >
    > char* name = "Ney Zunino";
    >
    > In spite of that assignment being allowed, it is not permitted to use
    > that pointer to modify the string literal. Next, Stroustrup adds that
    > this kind of error cannot generally be caught until runtime. As a matter
    > of fact, that's precisely what I have experienced with the following
    > test program:
    >
    > int main()
    > {
    > char* s = "Ney André de Mello Zunino";
    > s[2] = 'i';
    > }
    >
    > Both Microsoft Visual C++ 2003 and g++ 3.3.3 compiled it quietly and
    > both executables caused protection faults at runtime. Fine, it all went
    > just like Stroustrup had said, but what I don't understand is why. Why
    > is it so hard for a compiler to catch such violation? Isn't it clear
    > that the address assigned to 's' was that of a statically-allocated
    > literal?


    Why bother catching it if the Standard doesn't require catching it? The
    fact that you're trying to modify a literal becomes much less clear if
    you pass the pointer into another function which will modify the contents
    and even less clear if that function is in another translation unit. So,
    instead of requiring the implementations to watch out for those, the C++
    Standard simply says that an attempt to modify leads to undefined
    behavoiur. It's up to you as a programmer to prevent it. There are tools
    that go the extra mile to try to fish out those mistakes. Are they good?
    Those who use them can probably tell. I don't use them. I simply don't
    write code like in your example.

    V
     
    Victor Bazarov, Feb 14, 2005
    #1
    1. Advertising

  2. Ney André de Mello Zunino wrote:
    >
    >
    > Both Microsoft Visual C++ 2003 and g++ 3.3.3 compiled it quietly and
    > both executables caused protection faults at runtime. Fine, it all went
    > just like Stroustrup had said, but what I don't understand is why. Why
    > is it so hard for a compiler to catch such violation? Isn't it clear
    > that the address assigned to 's' was that of a statically-allocated literal?


    In this case: yes.
    In the general case: no

    void foo( char* check )
    {
    check[2] = 'n';
    }

    Now, does the above function attempt to modify a string literal?
    Nobody knows until runtime, when the caller of that function
    passes an address.

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Feb 14, 2005
    #2
    1. Advertising

  3. Hello.

    The following is a summary of what I have understood from reading
    Stroustrup's TCPL 3rd Edition's discourse on "string literals" (5.2.2).

    String literals are of type const char[n], where n is the length of the
    literal plus one. However, for compatibility reasons, assignment of such
    a literal to a non-const char* is allowed, e.g.:

    char* name = "Ney Zunino";

    In spite of that assignment being allowed, it is not permitted to use
    that pointer to modify the string literal. Next, Stroustrup adds that
    this kind of error cannot generally be caught until runtime. As a matter
    of fact, that's precisely what I have experienced with the following
    test program:

    int main()
    {
    char* s = "Ney André de Mello Zunino";
    s[2] = 'i';
    }

    Both Microsoft Visual C++ 2003 and g++ 3.3.3 compiled it quietly and
    both executables caused protection faults at runtime. Fine, it all went
    just like Stroustrup had said, but what I don't understand is why. Why
    is it so hard for a compiler to catch such violation? Isn't it clear
    that the address assigned to 's' was that of a statically-allocated literal?

    Thank you for your comments,

    --
    Ney André de Mello Zunino
     
    =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunino?=, Feb 14, 2005
    #3
  4. Victor Bazarov

    Noah Roberts Guest

    Karl Heinz Buchegger wrote:
    > Ney André de Mello Zunino wrote:
    > >
    > >
    > > Both Microsoft Visual C++ 2003 and g++ 3.3.3 compiled it quietly

    and
    > > both executables caused protection faults at runtime. Fine, it all

    went
    > > just like Stroustrup had said, but what I don't understand is why.

    Why
    > > is it so hard for a compiler to catch such violation? Isn't it

    clear
    > > that the address assigned to 's' was that of a statically-allocated

    literal?
    >
    > In this case: yes.
    > In the general case: no
    >
    > void foo( char* check )
    > {
    > check[2] = 'n';
    > }
    >
    > Now, does the above function attempt to modify a string literal?
    > Nobody knows until runtime, when the caller of that function
    > passes an address.


    To make the point more obvious, that same function could look like
    this:

    void foo(char check[])
    {
    check[2] = 'n';
    }

    and it wouldn't make a bit of difference in the end.

    On the other hand, if your literals are declaired const the compiler
    will generate a warning if you pass them as non-const parameters:

    const char *x = "ABCD";
    foo(x);

    will generate a warning complaining about the discarding of const in
    the call to foo...might even error in C++, not sure. The const keyword
    will protect you in many ways.
     
    Noah Roberts, Feb 14, 2005
    #4
  5. Karl Heinz Buchegger wrote:

    [...]

    > void foo( char* check )
    > {
    > check[2] = 'n';
    > }
    >
    > Now, does the above function attempt to modify a string literal?
    > Nobody knows until runtime, when the caller of that function
    > passes an address.


    Of course you and Victor are right. Thanks for clarifying it.

    --
    Ney André de Mello Zunino
     
    =?ISO-8859-1?Q?Ney_Andr=E9_de_Mello_Zunino?=, Feb 14, 2005
    #5
    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. John Goche
    Replies:
    8
    Views:
    16,573
  2. flamesrock
    Replies:
    8
    Views:
    551
    Hendrik van Rooyen
    Nov 24, 2006
  3. Nagaraj
    Replies:
    1
    Views:
    917
    Lionel B
    Mar 1, 2007
  4. Carter
    Replies:
    2
    Views:
    528
    Carter
    Mar 4, 2009
  5. mikie
    Replies:
    2
    Views:
    86
    Steven D'Aprano
    Mar 24, 2014
Loading...

Share This Page