Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. The Weird and The Wonderful
  4. Successfully writing to a string literal

Successfully writing to a string literal

Scheduled Pinned Locked Moved The Weird and The Wonderful
algorithmsdebuggingperformancelearning
6 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • I Offline
    I Offline
    Indivara
    wrote on last edited by
    #1

    Had to debug a crash today where the 32 bit build of an application was crashing, but the 64 bit build wasn't. There was a method that takes a string (char *) buffer as an in / out argument as follows.

    void SomeClass::someMethod(char * arg1, /* some other args */)
    {
    // do something

    arg1\[i\] = '\\0'; // i is a location within the buffer's size
    return;
    

    }

    The caller was supposed to call it with a variable, but one caller was passing a string literal, so naturally it caused an access violation.

    obj.someMethod("string_literal");

    However the 64 bit build was working fine. After some fiddling around, I discovered that it was due to the project's optimization settings. The assignement apparently has no effect, so the compiler was removing it in the 64 bit build. Disabling optimization caused the 64 bit build to crash too. Of course I had to come up with all kinds of crazy reasons first, thinking it was something to do with how 64 bit applications pass arguments, etc. No more in/outs. const char * is much safer, and will keep you sane (until you cast away the const, of course).

    F N 2 Replies Last reply
    0
    • I Indivara

      Had to debug a crash today where the 32 bit build of an application was crashing, but the 64 bit build wasn't. There was a method that takes a string (char *) buffer as an in / out argument as follows.

      void SomeClass::someMethod(char * arg1, /* some other args */)
      {
      // do something

      arg1\[i\] = '\\0'; // i is a location within the buffer's size
      return;
      

      }

      The caller was supposed to call it with a variable, but one caller was passing a string literal, so naturally it caused an access violation.

      obj.someMethod("string_literal");

      However the 64 bit build was working fine. After some fiddling around, I discovered that it was due to the project's optimization settings. The assignement apparently has no effect, so the compiler was removing it in the 64 bit build. Disabling optimization caused the 64 bit build to crash too. Of course I had to come up with all kinds of crazy reasons first, thinking it was something to do with how 64 bit applications pass arguments, etc. No more in/outs. const char * is much safer, and will keep you sane (until you cast away the const, of course).

      F Offline
      F Offline
      Freak30
      wrote on last edited by
      #2

      The assignment arg1[i] = '\0'; wouldn't work with a const char * (at least it shouldn't). ;) Also, shouldn't a string literal be implicitely cont char * and create a compiler error when being passed to a function that expects a char * as parameter?

      The good thing about pessimism is, that you are always either right or pleasently surprised.

      I 1 Reply Last reply
      0
      • I Indivara

        Had to debug a crash today where the 32 bit build of an application was crashing, but the 64 bit build wasn't. There was a method that takes a string (char *) buffer as an in / out argument as follows.

        void SomeClass::someMethod(char * arg1, /* some other args */)
        {
        // do something

        arg1\[i\] = '\\0'; // i is a location within the buffer's size
        return;
        

        }

        The caller was supposed to call it with a variable, but one caller was passing a string literal, so naturally it caused an access violation.

        obj.someMethod("string_literal");

        However the 64 bit build was working fine. After some fiddling around, I discovered that it was due to the project's optimization settings. The assignement apparently has no effect, so the compiler was removing it in the 64 bit build. Disabling optimization caused the 64 bit build to crash too. Of course I had to come up with all kinds of crazy reasons first, thinking it was something to do with how 64 bit applications pass arguments, etc. No more in/outs. const char * is much safer, and will keep you sane (until you cast away the const, of course).

        N Offline
        N Offline
        newton saber
        wrote on last edited by
        #3

        That is really interesting and a great write-up. Very clear too. It seems crazy to me, however, that the char * is "safer / saner" because it is somewhat more dangerous. The in/out should force more control, like requiring the user to create a variable on the stack first, right? Also, you said,

        Indivara wrote:

        so the compiler was removing it in the 64 bit build

        What do you mean "removing it"? Do you mean it actually just ignored the value sent in? That could drive you crazy, when you're trying to figure out why it isn't working.

        I 1 Reply Last reply
        0
        • N newton saber

          That is really interesting and a great write-up. Very clear too. It seems crazy to me, however, that the char * is "safer / saner" because it is somewhat more dangerous. The in/out should force more control, like requiring the user to create a variable on the stack first, right? Also, you said,

          Indivara wrote:

          so the compiler was removing it in the 64 bit build

          What do you mean "removing it"? Do you mean it actually just ignored the value sent in? That could drive you crazy, when you're trying to figure out why it isn't working.

          I Offline
          I Offline
          Indivara
          wrote on last edited by
          #4

          I meant using const char * arg1 would be a better choice in this case, not a generalization. The compiler was removing the last assignment arg1[i] = '\0' because it had no effect. The thing was thrown together in a hurry and the assignment was 'insurance' against the caller forgetting to add it. Had the reverse effect ironically.

          N 1 Reply Last reply
          0
          • F Freak30

            The assignment arg1[i] = '\0'; wouldn't work with a const char * (at least it shouldn't). ;) Also, shouldn't a string literal be implicitely cont char * and create a compiler error when being passed to a function that expects a char * as parameter?

            The good thing about pessimism is, that you are always either right or pleasently surprised.

            I Offline
            I Offline
            Indivara
            wrote on last edited by
            #5

            It only works the other way, you can't put a non-const pointer in a const (without casting). Ignore that, it is clearly incorrect, I'm the one who got it backwards. See below instead.

            const char * const_ptr;
            char * non_const_ptr;

            // The following three are OK
            const_ptr = non_const_ptr;
            const_ptr = "literal";
            non_const_ptr = "literal";

            // Causes a compiler error
            non_const_ptr = const_ptr;

            1 Reply Last reply
            0
            • I Indivara

              I meant using const char * arg1 would be a better choice in this case, not a generalization. The compiler was removing the last assignment arg1[i] = '\0' because it had no effect. The thing was thrown together in a hurry and the assignment was 'insurance' against the caller forgetting to add it. Had the reverse effect ironically.

              N Offline
              N Offline
              newton saber
              wrote on last edited by
              #6

              Ah, okay. I see what you mean now. Thanks for clarifying.

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups