modifying string literal

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • pvinodhkumar@gmail.com

    modifying string literal

    1)
    char* p = "Plato";
    p[4] = 'r'; // runtime error

    2)
    char c[6] = "Plato";
    c[4] = 'i';// ok.Why no runtime here?Why is the contradiction?
    cout << c << endl;

  • Victor Bazarov

    #2
    Re: modifying string literal

    pvinodhkumar@gm ail.com wrote:[color=blue]
    > 1)
    > char* p = "Plato";
    > p[4] = 'r'; // runtime error
    >
    > 2)
    > char c[6] = "Plato";
    > c[4] = 'i';// ok.Why no runtime here?Why is the contradiction?
    > cout << c << endl;[/color]

    It's not a contradiction. In (1) you're trying to modify the actual
    literal, which is a violation. In (2) you modify the array, which is
    initialised with a literal. It's a special case of using a literal.

    V

    Comment

    • Andrey Tarasevich

      #3
      Re: modifying string literal

      pvinodhkumar@gm ail.com wrote:[color=blue]
      > 1)
      > char* p = "Plato";
      > p[4] = 'r'; // runtime error[/color]

      You are modifying a string literal. String literals are not modifiable
      objects in C++.
      [color=blue]
      > 2)
      > char c[6] = "Plato";
      > c[4] = 'i';// ok.Why no runtime here?Why is the contradiction?
      > cout << c << endl;[/color]

      In tihs case you ar modifying array 'c'. Array 'c' is a modifiable
      object. No error.

      --
      Best regards,
      Andrey Tarasevich

      Comment

      • Andrew Koenig

        #4
        Re: modifying string literal

        <pvinodhkumar@g mail.com> wrote in message
        news:1102697575 .797142.217770@ c13g2000cwb.goo glegroups.com.. .[color=blue]
        > 1)
        > char* p = "Plato";
        > p[4] = 'r'; // runtime error[/color]

        Undefined behavior. The implementation is permitted to do anything it
        likes.

        The type of a string literal is really const char*, but you converted it to
        char*. This conversion is permitted for C compatibility. However, trying
        to change an element of the literal is prohibited. You should have written
        this:

        const char* p = "Plato";
        p[4] = 'r';

        and then the compiler would have caught your error at compile time.
        [color=blue]
        > 2)
        > char c[6] = "Plato";
        > c[4] = 'i';// ok.Why no runtime here?Why is the contradiction?
        > cout << c << endl;[/color]

        There is no contradiction. Why do you think there is?


        Comment

        • Ron Natalie

          #5
          Re: modifying string literal

          Victor Bazarov wrote:[color=blue]
          > pvinodhkumar@gm ail.com wrote:
          >[color=green]
          >> 1)
          >> char* p = "Plato";
          >> p[4] = 'r'; // runtime error
          >>
          >> 2)
          >> char c[6] = "Plato";
          >> c[4] = 'i';// ok.Why no runtime here?Why is the contradiction?
          >> cout << c << endl;[/color]
          >
          >
          > It's not a contradiction. In (1) you're trying to modify the actual
          > literal, which is a violation. In (2) you modify the array, which is
          > initialised with a literal. It's a special case of using a literal.[/color]

          It's not even a special case. You were right up until the last sentence.

          Comment

          • Andrey Tarasevich

            #6
            Re: modifying string literal

            Ron Natalie wrote:[color=blue][color=green]
            >> ...[color=darkred]
            >>> 1)
            >>> char* p = "Plato";
            >>> p[4] = 'r'; // runtime error
            >>>
            >>> 2)
            >>> char c[6] = "Plato";
            >>> c[4] = 'i';// ok.Why no runtime here?Why is the contradiction?
            >>> cout << c << endl;[/color]
            >>
            >>
            >> It's not a contradiction. In (1) you're trying to modify the actual
            >> literal, which is a violation. In (2) you modify the array, which is
            >> initialised with a literal. It's a special case of using a literal.[/color]
            >
            > It's not even a special case. You were right up until the last sentence.[/color]

            Actually, this use of string literal is often referred to (see
            comp.lang.c FAQ, for example) as a special case when array type doesn't
            decay to pointer type, i.e. this is the one and only context where array
            is actually copyable as a whole (or at least seems to be). Although this
            is not very relevant to the OP's question...

            --
            Best regards,
            Andrey Tarasevich

            Comment

            • Andrew Koenig

              #7
              Re: modifying string literal

              "Ron Natalie" <ron@sensor.com > wrote in message
              news:41ba16cf$0 $1586$9a6e19ea@ news.newshostin g.com...
              [color=blue][color=green]
              >> It's not a contradiction. In (1) you're trying to modify the actual
              >> literal, which is a violation. In (2) you modify the array, which is
              >> initialised with a literal. It's a special case of using a literal.[/color][/color]
              [color=blue]
              > It's not even a special case. You were right up until the last sentence.[/color]

              It is, kind of.

              char c[] = "abc";

              is equivalent to

              char c[] = { 'a', 'b', 'c', '\0' };

              which doesn't happen without a specific rule to make it happen.


              Comment

              • Ron Natalie

                #8
                Re: modifying string literal

                Andrey Tarasevich wrote:
                [color=blue]
                >
                > Actually, this use of string literal is often referred to (see
                > comp.lang.c FAQ, for example) as a special case when array type doesn't
                > decay to pointer type, i.e. this is the one and only context where array
                > is actually copyable as a whole (or at least seems to be). Although this
                > is not very relevant to the OP's question...
                >[/color]

                I have no clue what this means. There's nothing special here about
                string arrays. There are a handful of cases where ALL arrays are treated
                as real types rather than implicitly convertd to pointers. The only
                thing "special" here is that other than string literals, there are no
                array literals.

                Comment

                • pvinodhkumar@gmail.com

                  #9
                  Re: modifying string literal

                  The type of a string literal is really const char*, but you converted
                  it to
                  char*. This conversion is permitted for C compatibility. However,
                  trying
                  to change an element of the literal is prohibited.

                  Though the syntax is
                  char* p = "Plato";
                  internally it is
                  const char* p = "Plato";

                  OK.

                  Since it is only internally const char* it gives a runtime error?






                  Yes there is no contradiction.
                  char* p = "Plato";
                  I forgot to see p as const char*.

                  Comment

                  • Andrey Tarasevich

                    #10
                    Re: modifying string literal

                    pvinodhkumar@gm ail.com wrote:[color=blue]
                    > The type of a string literal is really const char*, but you converted
                    > it to char*.[/color]

                    The type of string literal is 'const char[N]', not 'const char*'.
                    [color=blue]
                    > This conversion is permitted for C compatibility. However,
                    > trying to change an element of the literal is prohibited.[/color]

                    Yes.
                    [color=blue]
                    > Though the syntax is
                    > char* p = "Plato";
                    > internally it is
                    > const char* p = "Plato";
                    >
                    > OK.[/color]

                    No. Internally it still is 'char* p'. In general case
                    const-qualification of an access path is not related to
                    const-qualification of the object this path leads to.
                    [color=blue]
                    > Since it is only internally const char* it gives a runtime error?[/color]

                    It gives a runtime error because you are trying to modify an
                    non-modifiable object - string literal. It has nothing to do with the
                    pointer 'p' itself.
                    [color=blue]
                    > Yes there is no contradiction.
                    > char* p = "Plato";
                    > I forgot to see p as const char*.[/color]

                    'p' is not a 'const char*'. What would really make sense is declare it
                    as 'const char* p' explicitly instead of tryig to "remember to see" it
                    as such. Don't use the deprecated 'string literal -> char*' conversion
                    unless you have a very good reason to do so.

                    --
                    Best regards,
                    Andrey Tarasevich

                    Comment

                    • Andrew Koenig

                      #11
                      Re: modifying string literal

                      "Andrey Tarasevich" <andreytarasevi ch@hotmail.com> wrote in message
                      news:g7ednTCkAs 1e2CbcRVn-qQ@comcast.com. ..
                      [color=blue][color=green]
                      >> The type of a string literal is really const char*, but you converted
                      >> it to char*.[/color][/color]
                      [color=blue]
                      > The type of string literal is 'const char[N]', not 'const char*'.[/color]

                      Picky, picky. It's really const char[N+1] because of the null terminator.


                      Comment

                      • Victor Bazarov

                        #12
                        Re: modifying string literal

                        "Andrew Koenig" <ark@acm.org> wrote...[color=blue]
                        > "Andrey Tarasevich" <andreytarasevi ch@hotmail.com> wrote in message
                        > news:g7ednTCkAs 1e2CbcRVn-qQ@comcast.com. ..
                        >[color=green][color=darkred]
                        >>> The type of a string literal is really const char*, but you converted
                        >>> it to char*.[/color][/color]
                        >[color=green]
                        >> The type of string literal is 'const char[N]', not 'const char*'.[/color]
                        >
                        > Picky, picky. It's really const char[N+1] because of the null terminator.[/color]

                        :-) It depends on how you define 'N'. In fact, N in Andrey's answer does
                        most likely account for the null terminator because the literal "" cannot
                        have the type 'const char[0]' since zero-sized arrays are not allowed.

                        V


                        Comment

                        • Andrey Tarasevich

                          #13
                          Re: modifying string literal

                          Andrew Koenig wrote:[color=blue]
                          > ...[color=green][color=darkred]
                          >>> The type of a string literal is really const char*, but you converted
                          >>> it to char*.[/color][/color]
                          >[color=green]
                          >> The type of string literal is 'const char[N]', not 'const char*'.[/color]
                          >
                          > Picky, picky. It's really const char[N+1] because of the null terminator.
                          > ...[/color]

                          Unjustified :) Initially I wanted to say 'const char[N+1]' but then I
                          thought that in this case I'll probably need to explain what 'N' is. So,
                          for brevity sake, I just said it's 'const char[N]' and said nothing
                          about 'N' (it is not really relevant within the context of this topic).

                          --
                          Best regards,
                          Andrey Tarasevich

                          Comment

                          Working...