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. General Programming
  3. C / C++ / MFC
  4. differentiating between literal strings and char pointers [modified]

differentiating between literal strings and char pointers [modified]

Scheduled Pinned Locked Moved C / C++ / MFC
announcementdatabasevisual-studioquestion
16 Posts 5 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.
  • D Offline
    D Offline
    dburns
    wrote on last edited by
    #1

    Hi, Suppose I have a method foo that takes a const char* param. I have a case where I can be more efficient if the caller passes in a "quoted literal string" vs the contents of some arbitrary buffer (because I don't have to copy the string data in the first case). ((UPDATE: To be clear, the class with method foo needs to store the supplied string away for later access, internally. For a literal string, it's safe to store the pointer only. For a non-literal, it's necessary to copy the data in case the original caller's buffer goes away or is modified before the class instance goes away.)) Pretty sure the answer is "you can't", but I thought I'd check if anyone can think of a way to overload the method foo such that one version is invoked for char buff[100]; ... const char* p_buff = buff; myclass.foo(p_buff) and the second version is invoked for myclass.foo("literal string") ? I can't change the name of foo or have the caller specify explicitly which one they want. This sample is just an illustration. Thanks! DB -- modified at 12:11 Friday 3rd August, 2007

    C D C 3 Replies Last reply
    0
    • D dburns

      Hi, Suppose I have a method foo that takes a const char* param. I have a case where I can be more efficient if the caller passes in a "quoted literal string" vs the contents of some arbitrary buffer (because I don't have to copy the string data in the first case). ((UPDATE: To be clear, the class with method foo needs to store the supplied string away for later access, internally. For a literal string, it's safe to store the pointer only. For a non-literal, it's necessary to copy the data in case the original caller's buffer goes away or is modified before the class instance goes away.)) Pretty sure the answer is "you can't", but I thought I'd check if anyone can think of a way to overload the method foo such that one version is invoked for char buff[100]; ... const char* p_buff = buff; myclass.foo(p_buff) and the second version is invoked for myclass.foo("literal string") ? I can't change the name of foo or have the caller specify explicitly which one they want. This sample is just an illustration. Thanks! DB -- modified at 12:11 Friday 3rd August, 2007

      C Offline
      C Offline
      CPallini
      wrote on last edited by
      #2

      dburns wrote:

      Hi, Suppose I have a method foo that takes a const char* param. I have a case where I can be more efficient if the caller passes in a "quoted literal string" vs the contents of some arbitrary buffer (because I don't have to copy the string data in the first case).

      IMHO, You completely miss the efficience target... i.e. don't bother about. :)

      If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.

      D 1 Reply Last reply
      0
      • C CPallini

        dburns wrote:

        Hi, Suppose I have a method foo that takes a const char* param. I have a case where I can be more efficient if the caller passes in a "quoted literal string" vs the contents of some arbitrary buffer (because I don't have to copy the string data in the first case).

        IMHO, You completely miss the efficience target... i.e. don't bother about. :)

        If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.

        D Offline
        D Offline
        dburns
        wrote on last edited by
        #3

        CPallini wrote:

        IMHO, You completely miss the efficience target...

        Actually we've done profiling on this code and it really does matter. You may be picturing one or two invocations but picture 10s of millions :-)

        C 1 Reply Last reply
        0
        • D dburns

          CPallini wrote:

          IMHO, You completely miss the efficience target...

          Actually we've done profiling on this code and it really does matter. You may be picturing one or two invocations but picture 10s of millions :-)

          C Offline
          C Offline
          CPallini
          wrote on last edited by
          #4

          But you don't need to copy anything, simply cast the pointer! :)

          If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.

          D 1 Reply Last reply
          0
          • D dburns

            Hi, Suppose I have a method foo that takes a const char* param. I have a case where I can be more efficient if the caller passes in a "quoted literal string" vs the contents of some arbitrary buffer (because I don't have to copy the string data in the first case). ((UPDATE: To be clear, the class with method foo needs to store the supplied string away for later access, internally. For a literal string, it's safe to store the pointer only. For a non-literal, it's necessary to copy the data in case the original caller's buffer goes away or is modified before the class instance goes away.)) Pretty sure the answer is "you can't", but I thought I'd check if anyone can think of a way to overload the method foo such that one version is invoked for char buff[100]; ... const char* p_buff = buff; myclass.foo(p_buff) and the second version is invoked for myclass.foo("literal string") ? I can't change the name of foo or have the caller specify explicitly which one they want. This sample is just an illustration. Thanks! DB -- modified at 12:11 Friday 3rd August, 2007

            D Offline
            D Offline
            David Crow
            wrote on last edited by
            #5

            dburns wrote:

            ..."quoted literal string" vs the contents of some arbitrary buffer (because I don't have to copy the string data in the first case).

            Not exactly sure what you mean by this. :confused:

            dburns wrote:

            char buff[100]; ... const char* p_buff = buff; myclass.foo(p_buff)

            Why use p_buff when you can pass buff directly to the foo() method?


            "A good athlete is the result of a good and worthy opponent." - David Crow

            "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

            D 1 Reply Last reply
            0
            • C CPallini

              But you don't need to copy anything, simply cast the pointer! :)

              If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.

              D Offline
              D Offline
              dburns
              wrote on last edited by
              #6

              We really DO need to copy the data because the C++ object that I called "myclass" may outlive the buffer that contained the original data. If we just stored the supplied pointer, then it would be pointing to a buffer on the stack, which would be wiped out when the function returned. Then the "myclass" object would have a pointer to garbage. If the pointer is truly a "literal string" then that's not an issue. That's why I'm trying to detect that case to be more efficient.

              C 1 Reply Last reply
              0
              • D dburns

                We really DO need to copy the data because the C++ object that I called "myclass" may outlive the buffer that contained the original data. If we just stored the supplied pointer, then it would be pointing to a buffer on the stack, which would be wiped out when the function returned. Then the "myclass" object would have a pointer to garbage. If the pointer is truly a "literal string" then that's not an issue. That's why I'm trying to detect that case to be more efficient.

                C Offline
                C Offline
                CPallini
                wrote on last edited by
                #7

                But (in the OP) you're not copying data, you're just copying the address. ...is there a mistake in the air? :) MODIFIED: Or are you're talking about an internal copy done by you're class? in that case you've simply to differentiate calls to foo() member, for instance:

                foo(const char * pBuffer)
                {
                // perform a copy of the given buffer
                ...
                // call the copy-free member
                foo_without_copy(pCopiedBuffer);
                }
                foo_without_copy( const char * pBuffer)
                {
                ...
                }

                :)

                If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.

                D 1 Reply Last reply
                0
                • D David Crow

                  dburns wrote:

                  ..."quoted literal string" vs the contents of some arbitrary buffer (because I don't have to copy the string data in the first case).

                  Not exactly sure what you mean by this. :confused:

                  dburns wrote:

                  char buff[100]; ... const char* p_buff = buff; myclass.foo(p_buff)

                  Why use p_buff when you can pass buff directly to the foo() method?


                  "A good athlete is the result of a good and worthy opponent." - David Crow

                  "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

                  D Offline
                  D Offline
                  dburns
                  wrote on last edited by
                  #8

                  David,

                  DavidCrow wrote:

                  Why use p_buff when you can pass buff directly to the foo() method?

                  I could have passed buff in directly, yes. What I was trying to illustrate is that the input parameter might actually be a const char* pointer, but in that case I don't know where the underlying data came from. It could be from a buffer, as in the example, so I would have to copy the data in this case. Unfortunately, a "quoted string" is also a const char* pointer, so it would naturally choose the same overridden foo. But if it's a "quoted string" then I don't have to copy the underlying data, so the goal is to differentiate between these two cases. Like I said, probably not possible in C++, just checking. DB

                  1 Reply Last reply
                  0
                  • C CPallini

                    But (in the OP) you're not copying data, you're just copying the address. ...is there a mistake in the air? :) MODIFIED: Or are you're talking about an internal copy done by you're class? in that case you've simply to differentiate calls to foo() member, for instance:

                    foo(const char * pBuffer)
                    {
                    // perform a copy of the given buffer
                    ...
                    // call the copy-free member
                    foo_without_copy(pCopiedBuffer);
                    }
                    foo_without_copy( const char * pBuffer)
                    {
                    ...
                    }

                    :)

                    If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.

                    D Offline
                    D Offline
                    dburns
                    wrote on last edited by
                    #9

                    CPallini wrote:

                    Or are you're talking about an internal copy done by you're class?

                    Yes, that's exactly right. Perhaps you've illustrated it better than I did in the original post. However, I can't use foo and foo_without_copy. In the OP I indicated that I can't have the caller make the explicit choice. I need the compiler to differentiate, if it's possible. I doubt it is. Maybe I'm just lazy but we're talking a million lines of code here and I'd rather the compiler did the work rather than me searching and changing each one :-)

                    D L 2 Replies Last reply
                    0
                    • D dburns

                      CPallini wrote:

                      Or are you're talking about an internal copy done by you're class?

                      Yes, that's exactly right. Perhaps you've illustrated it better than I did in the original post. However, I can't use foo and foo_without_copy. In the OP I indicated that I can't have the caller make the explicit choice. I need the compiler to differentiate, if it's possible. I doubt it is. Maybe I'm just lazy but we're talking a million lines of code here and I'd rather the compiler did the work rather than me searching and changing each one :-)

                      D Offline
                      D Offline
                      David Crow
                      wrote on last edited by
                      #10

                      dburns wrote:

                      I need the compiler to differentiate, if it's possible. I doubt it is.

                      It makes me wonder if the two addresses would be in different areas. String literals would be in the stack area, whereas dynamically-allocated memory would be in the heap. Hmmm...


                      "A good athlete is the result of a good and worthy opponent." - David Crow

                      "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

                      D L 2 Replies Last reply
                      0
                      • D David Crow

                        dburns wrote:

                        I need the compiler to differentiate, if it's possible. I doubt it is.

                        It makes me wonder if the two addresses would be in different areas. String literals would be in the stack area, whereas dynamically-allocated memory would be in the heap. Hmmm...


                        "A good athlete is the result of a good and worthy opponent." - David Crow

                        "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

                        D Offline
                        D Offline
                        dburns
                        wrote on last edited by
                        #11

                        Now that's outside-the-box thinking!! I think I'm a little chicken to go that route though...

                        1 Reply Last reply
                        0
                        • D dburns

                          CPallini wrote:

                          Or are you're talking about an internal copy done by you're class?

                          Yes, that's exactly right. Perhaps you've illustrated it better than I did in the original post. However, I can't use foo and foo_without_copy. In the OP I indicated that I can't have the caller make the explicit choice. I need the compiler to differentiate, if it's possible. I doubt it is. Maybe I'm just lazy but we're talking a million lines of code here and I'd rather the compiler did the work rather than me searching and changing each one :-)

                          L Offline
                          L Offline
                          led mike
                          wrote on last edited by
                          #12

                          dburns wrote:

                          I'd rather the compiler did the work

                          This is a design issue. Compilers are NOT intended to "design" or make up for a poor design.

                          1 Reply Last reply
                          0
                          • D David Crow

                            dburns wrote:

                            I need the compiler to differentiate, if it's possible. I doubt it is.

                            It makes me wonder if the two addresses would be in different areas. String literals would be in the stack area, whereas dynamically-allocated memory would be in the heap. Hmmm...


                            "A good athlete is the result of a good and worthy opponent." - David Crow

                            "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

                            L Offline
                            L Offline
                            led mike
                            wrote on last edited by
                            #13

                            He states this is a performance issue. Analyzing memory addresses at runtime would defeat the purpose yes?

                            D 1 Reply Last reply
                            0
                            • L led mike

                              He states this is a performance issue. Analyzing memory addresses at runtime would defeat the purpose yes?

                              D Offline
                              D Offline
                              David Crow
                              wrote on last edited by
                              #14

                              They're just numbers, so I wouldn't think the impact would be that substantial. Without empirical data, however, I wouldn't know for sure.


                              "A good athlete is the result of a good and worthy opponent." - David Crow

                              "To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne

                              1 Reply Last reply
                              0
                              • D dburns

                                Hi, Suppose I have a method foo that takes a const char* param. I have a case where I can be more efficient if the caller passes in a "quoted literal string" vs the contents of some arbitrary buffer (because I don't have to copy the string data in the first case). ((UPDATE: To be clear, the class with method foo needs to store the supplied string away for later access, internally. For a literal string, it's safe to store the pointer only. For a non-literal, it's necessary to copy the data in case the original caller's buffer goes away or is modified before the class instance goes away.)) Pretty sure the answer is "you can't", but I thought I'd check if anyone can think of a way to overload the method foo such that one version is invoked for char buff[100]; ... const char* p_buff = buff; myclass.foo(p_buff) and the second version is invoked for myclass.foo("literal string") ? I can't change the name of foo or have the caller specify explicitly which one they want. This sample is just an illustration. Thanks! DB -- modified at 12:11 Friday 3rd August, 2007

                                C Offline
                                C Offline
                                cp9876
                                wrote on last edited by
                                #15

                                Guess you can't use a string type instead of a char*? If you used a string type throughout your application, and if that type used reference counting, then the only strings you would have to copy would be the literals, the others you would simply increase the reference count. This would clearly change your efficiency - no idea if for better or worse.


                                Peter "Until the invention of the computer, the machine gun was the device that enabled humans to make the most mistakes in the smallest amount of time."

                                D 1 Reply Last reply
                                0
                                • C cp9876

                                  Guess you can't use a string type instead of a char*? If you used a string type throughout your application, and if that type used reference counting, then the only strings you would have to copy would be the literals, the others you would simply increase the reference count. This would clearly change your efficiency - no idea if for better or worse.


                                  Peter "Until the invention of the computer, the machine gun was the device that enabled humans to make the most mistakes in the smallest amount of time."

                                  D Offline
                                  D Offline
                                  dburns
                                  wrote on last edited by
                                  #16

                                  :-) Kind of funny you should suggest that, because that's almost exactly what we have today. Once our string type has copied data from a buffer, then it is ref-counted to avoid further copies. We have a means to specify that the input string is a literal quoted string, in which case no copy of the string data is made at all (and ref-counting is not needed). However in most cases programmers seem to use the version that copies string data even when they're supplying a literal quoted string. No reason other than they have other things on their mind when writing code, and don't seem to remember such details. So my goal was to detect this and either automatically be more efficient, or give them a compiler error that forces them to use the more efficient version. As an update I've found I can use "const" to detect the use of a non-literal buffer in some cases, but not all. For example: char buff[100]; ... StringClass s1(buff); // Works: will use the non-const constructor and will copy. const char* ptr = ...; // possibly points at some local temp buffer StringClass s2(ptr); // Can't distinguish between this case... StringClass s3("hello"); //... and this case So I would like to distinguish between the s2 and the s3 case (the s2 case should be copied since there's no telling where the pointer is pointing, and the s3 case should not be copied). I don't think C++ is going to let me do that. Thanks for the ideas...

                                  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