const char* vs string

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Javier

    const char* vs string

    Hello,
    in which cases is it better the use of "const char*" to "string" (or
    even const string &).
    I mean, in STL (http://www.sgi.com/tech/stl/hash_map.html) I see:

    hash_map<const char*, int, hash<const char*>, eqstrmonths;
    months["january"] = 31;

    I think it is for the use in calls like function("my string"), but, is
    it really necessary to define funcion(const char*) besides
    function(const string &) in my public member functions?

    I have read that the compiler does too much temporaries variables in
    such cases, but is it true?

    And what about in:

    string mystring = "my string" + string1 + " is " + string2;

    or in:

    cout << string << " hello" << string2 << " my name is " << string3;

    Thanks.

  • Ian Collins

    #2
    Re: const char* vs string

    Javier wrote:
    Hello,
    in which cases is it better the use of "const char*" to "string" (or
    even const string &).
    Seldom.

    The only real reason is interfacing with C code.
    I mean, in STL (http://www.sgi.com/tech/stl/hash_map.html) I see:
    >
    hash_map<const char*, int, hash<const char*>, eqstrmonths;
    months["january"] = 31;
    >
    I think it is for the use in calls like function("my string"), but, is
    it really necessary to define funcion(const char*) besides
    function(const string &) in my public member functions?
    >
    I have read that the compiler does too much temporaries variables in
    such cases, but is it true?
    >
    And what about in:
    >
    string mystring = "my string" + string1 + " is " + string2;
    >
    or in:
    >
    cout << string << " hello" << string2 << " my name is " << string3;
    >
    What about them? I don't see how these link to your question.

    --
    Ian Collins.

    Comment

    • Javier

      #3
      Re: const char* vs string

      On 1 jun, 12:12, Ian Collins <ian-n...@hotmail.co mwrote:
      Javier wrote:
      Hello,
      in which cases is it better the use of "const char*" to "string" (or
      even const string &).
      >
      Seldom.
      >
      The only real reason is interfacing with C code.
      >
      >
      >>
      hash_map<const char*, int, hash<const char*>, eqstrmonths;
      months["january"] = 31;
      >
      I think it is for the use in calls like function("my string"), but, is
      it really necessary to define funcion(const char*) besides
      function(const string &) in my public member functions?
      >
      I have read that the compiler does too much temporaries variables in
      such cases, but is it true?
      >
      And what about in:
      >
      string mystring = "my string" + string1 + " is " + string2;
      Does the compiler create temporaries in this case? Is it important? I
      mean, is it better to write?:

      string mystring = "my string";
      mystring += string1;
      mystring += " is ";
      mystring += string2;

      than:

      string mystring = "my string" + string1 + " is " + string2;
      >
      or in:
      >
      cout << string << " hello" << string2 << " my name is " << string3;
      Same question.
      >
      What about them? I don't see how these link to your question.
      >
      --
      Ian Collins.
      Thanks.

      Comment

      • Dizzy

        #4
        Re: const char* vs string

        Javier wrote:
        >>
        string mystring = "my string" + string1 + " is " + string2;
        >
        Does the compiler create temporaries in this case? Is it important? I
        mean, is it better to write?:
        >
        string mystring = "my string";
        mystring += string1;
        mystring += " is ";
        mystring += string2;
        >
        than:
        >
        string mystring = "my string" + string1 + " is " + string2;
        Yes the second version does create temporaries and additional copies (tho
        RVO might reduce some there). However, the second version is clearer than
        the first one, seems more natural and unless you do that thousands of times
        per second it shouldn't matter the additional cost (ie unless your code
        profiling points this as a source of bottleneck). Also I think that in the
        future with rvalue references and move semantics that overhead will be
        eliminated anyway.

        --
        Dizzy

        Comment

        • Noah Roberts

          #5
          Re: const char* vs string

          Javier wrote:
          string mystring = "my string" + string1 + " is " + string2;
          Does this even compile? I wouldn't expect it to.

          Comment

          • Zeppe

            #6
            Re: const char* vs string

            Noah Roberts wrote:
            Javier wrote:
            >
            >string mystring = "my string" + string1 + " is " + string2;
            >
            Does this even compile? I wouldn't expect it to.
            Why not? The operator+(const char*, const std::string&) is defined.

            Regards,

            Zeppe

            Comment

            • Jacek Dziedzic

              #7
              Re: const char* vs string

              Javier wrote:
              Hello,
              in which cases is it better the use of "const char*" to "string" (or
              even const string &).
              Almost never. The only reason I've ever used it when I needed
              read/write access to a fixed-size raw buffer of chars that were
              copied across processors using MPI without construction/destruction.

              The other reasons could be "to be able to compile the program
              with a really ancient C++ compiler which does not recognize string"
              and "to show people how nasty bugs appear when using char*" <eg>.

              HTH,
              - J.

              Comment

              • Juha Nieminen

                #8
                Re: const char* vs string

                Javier wrote:
                in which cases is it better the use of "const char*" to "string" (or
                even const string &).
                I would say that "const char*" is ok when you really have
                compile-time constant strings, especially if you don't really need
                to know their size.

                Example:

                const char* const KEYWORDS[] =
                { "keyword1", "keyword2", "keyword3", ... };

                These are just compile-time constants which are not modified during
                the execution of the program, so I would say that it's not really
                necessary to have them as std::strings. If at some point you really
                need to do some handling with those, it's pretty trivial to create
                a std::string from them, like: std::string keyword = KEYWORDS[1];

                Comment

                • Ricardo

                  #9
                  Re: const char* vs string

                  void doSomething(std ::string& param)
                  {

                  }
                  ....

                  doSomething("Do That");

                  doSomething will certainly call std::string constructor, alloc memory,
                  copy de contents, deallocate and its destructor will do something else
                  if it has some reference counter...

                  Why do that if "DoThat" will be stored in the data segement??? I am
                  not an expert but I am pretty sure you have a performance overhead
                  which is the price for the convenience...

                  So, is it never recommended using [const] char* instead of
                  std::string? I think "never" should be changed to "never if
                  performance doesn't matter".

                  Jose Ricardo


                  Comment

                  • Craig Scott

                    #10
                    Re: const char* vs string

                    On Jun 1, 8:12 pm, Ian Collins <ian-n...@hotmail.co mwrote:
                    Javier wrote:
                    Hello,
                    in which cases is it better the use of "const char*" to "string" (or
                    even const string &).
                    >
                    Seldom.
                    >
                    The only real reason is interfacing with C code.
                    Actually, it can also matter for C++ code. If you are using shared
                    libraries, then you need to be aware that the C++ standard does not
                    guarantee that std::string is safe to use anywhere in a shared
                    library's interface (it mentions absolutely nothing about shared
                    libraries at all). This is frequently a surprise to many C++
                    developers, but Scott Meyers and others give this topic a good
                    treatment in their various books (sorry, I don't have them on hand at
                    the moment, but one of the Effective C++/STL books I think). In short,
                    unless you can guarantee that your code is being compiled with exactly
                    the same compiler version as the library you are calling and that you
                    are using exactly the same compiler flags, then the only types safe to
                    use in the shared library's interface are POD types and pointers (but
                    it would be potentially unsafe to dereference these pointers).

                    So for the original poster's question, const char* will always be
                    portable and is safe to use in a library interface, whereas
                    std::string might or might not be safe depending on the compiler and
                    flags used. In real world code, we've found that this does matter and
                    we have defined our interfaces accordingly. YMMV.

                    --
                    Computational Fluid Dynamics, CSIRO (CMIS)
                    Melbourne, Australia


                    Comment

                    • red floyd

                      #11
                      Re: const char* vs string

                      Craig Scott wrote:
                      On Jun 1, 8:12 pm, Ian Collins <ian-n...@hotmail.co mwrote:
                      >Javier wrote:
                      >>Hello,
                      >>in which cases is it better the use of "const char*" to "string" (or
                      >>even const string &).
                      >Seldom.
                      >>
                      >The only real reason is interfacing with C code.
                      >
                      Actually, it can also matter for C++ code. If you are using shared
                      libraries, then you need to be aware that the C++ standard does not
                      guarantee that std::string is safe to use anywhere in a shared
                      library's interface (it mentions absolutely nothing about shared
                      libraries at all).
                      Precisely correct in tha tthe Standard doesn't mention shared libraries.
                      Therefore the C++ standard does not guarantee that const char* is safe
                      to use anywhere in a shared library's interface either.

                      Comment

                      • Ian Collins

                        #12
                        Re: const char* vs string

                        Craig Scott wrote:
                        On Jun 1, 8:12 pm, Ian Collins <ian-n...@hotmail.co mwrote:
                        >Javier wrote:
                        >>Hello,
                        >>in which cases is it better the use of "const char*" to "string" (or
                        >>even const string &).
                        >Seldom.
                        >>
                        >The only real reason is interfacing with C code.
                        >
                        Actually, it can also matter for C++ code. If you are using shared
                        libraries, then you need to be aware that the C++ standard does not
                        guarantee that std::string is safe to use anywhere in a shared
                        library's interface (it mentions absolutely nothing about shared
                        libraries at all). This is frequently a surprise to many C++
                        developers, but Scott Meyers and others give this topic a good
                        treatment in their various books (sorry, I don't have them on hand at
                        the moment, but one of the Effective C++/STL books I think). In short,
                        unless you can guarantee that your code is being compiled with exactly
                        the same compiler version as the library you are calling and that you
                        are using exactly the same compiler flags, then the only types safe to
                        use in the shared library's interface are POD types and pointers (but
                        it would be potentially unsafe to dereference these pointers).
                        >
                        The same applies to any C++ linkage function as well. If you want to
                        have maximum compatibility, you have to stick to extern "C" linkage
                        functions, or choose a compiler that guarantees ABI compatibility.

                        --
                        Ian Collins.

                        Comment

                        • James Kanze

                          #13
                          Re: const char* vs string

                          On Jun 3, 2:44 pm, Craig Scott <audiofana...@g mail.comwrote:
                          On Jun 1, 8:12 pm, Ian Collins <ian-n...@hotmail.co mwrote:
                          Javier wrote:
                          in which cases is it better the use of "const char*" to "string" (or
                          even const string &).
                          Seldom.
                          The only real reason is interfacing with C code.
                          Actually, it can also matter for C++ code. If you are using shared
                          libraries, then you need to be aware that the C++ standard does not
                          guarantee that std::string is safe to use anywhere in a shared
                          library's interface (it mentions absolutely nothing about shared
                          libraries at all).
                          Strictly speaking, that's true for int as well. If all you're
                          counting on is what the C++ standard says, then you can't count
                          on int working in a dynamically linked object either.
                          This is frequently a surprise to many C++
                          developers, but Scott Meyers and others give this topic a good
                          treatment in their various books (sorry, I don't have them on hand at
                          the moment, but one of the Effective C++/STL books I think). In short,
                          unless you can guarantee that your code is being compiled with exactly
                          the same compiler version as the library you are calling and that you
                          are using exactly the same compiler flags, then the only types safe to
                          use in the shared library's interface are POD types and pointers (but
                          it would be potentially unsafe to dereference these pointers).
                          Not even that: you can't be sure at all about any struct, since
                          padding may depend on compiler options. For that matter, you
                          can't be sure about long---I've had the byte order of a long
                          change from one version of the compiler to the next, and you
                          certainly can't be sure about pointers, whose size depends on
                          compiler options.

                          In practice, there will be a set of options you can play with,
                          over a set of versions of the compiler.
                          So for the original poster's question, const char* will always be
                          portable and is safe to use in a library interface,
                          Except when the size of a pointer depends on a compiler option
                          (the usual case today, where all of the platforms I know support
                          both 32 and 64 bit pointers).

                          In fact, you're never really portable. The library supplier
                          should specify the restrictions, but in general, using
                          std::string entails no more risk than using any other struct.
                          whereas
                          std::string might or might not be safe depending on the compiler and
                          flags used. In real world code, we've found that this does matter and
                          we have defined our interfaces accordingly.
                          In the real world, we use std::string and std::vector without
                          problems, over a variety of compilers and systems.

                          --
                          James Kanze (Gabi Software) email: james.kanze@gma il.com
                          Conseils en informatique orientée objet/
                          Beratung in objektorientier ter Datenverarbeitu ng
                          9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                          Comment

                          • Craig Scott

                            #14
                            Re: const char* vs string

                            Actually, it can also matter for C++ code. If you are using shared
                            libraries, then you need to be aware that the C++ standard does not
                            guarantee that std::string is safe to use anywhere in a shared
                            library's interface (it mentions absolutely nothing about shared
                            libraries at all).
                            >
                            Strictly speaking, that's true for int as well. If all you're
                            counting on is what the C++ standard says, then you can't count
                            on int working in a dynamically linked object either.
                            Fair enough.

                            This is frequently a surprise to many C++
                            developers, but Scott Meyers and others give this topic a good
                            treatment in their various books (sorry, I don't have them on hand at
                            the moment, but one of the Effective C++/STL books I think). In short,
                            unless you can guarantee that your code is being compiled with exactly
                            the same compiler version as the library you are calling and that you
                            are using exactly the same compiler flags, then the only types safe to
                            use in the shared library's interface are POD types and pointers (but
                            it would be potentially unsafe to dereference these pointers).
                            >
                            Not even that: you can't be sure at all about any struct, since
                            padding may depend on compiler options. For that matter, you
                            can't be sure about long---I've had the byte order of a long
                            change from one version of the compiler to the next, and you
                            certainly can't be sure about pointers, whose size depends on
                            compiler options.
                            Um, I believe I said exactly the same compiler version and flags. If
                            you use the same settings on the same compiler for the same platform,
                            you should get the same byte order, padding, pointer size, etc.

                            In practice, there will be a set of options you can play with,
                            over a set of versions of the compiler.
                            >
                            So for the original poster's question, const char* will always be
                            portable and is safe to use in a library interface,
                            >
                            Except when the size of a pointer depends on a compiler option
                            (the usual case today, where all of the platforms I know support
                            both 32 and 64 bit pointers).
                            Agreed. If you change a compiler option which causes a different
                            pointer size, you should expect things to explode. ;) I think the
                            main point is to know what compiler and flags were used to build the
                            shared library you want to use. It is then your responsibility to use
                            compatible flags for your own code.

                            In fact, you're never really portable. The library supplier
                            should specify the restrictions, but in general, using
                            std::string entails no more risk than using any other struct.
                            Unless different modules have their own memory heap (we have
                            encountered situations where some do). Then you run the risk of having
                            memory allocated in one module and then when you resize the string,
                            vector, etc in another module the memory needs to be freed in that
                            module and BOOM! Even if memory is always allocated/deallocated from
                            the one heap, having std::string, std::vector or any other container
                            in the interface prevents you from doing some cool stuff like use an
                            alternate STL implementation in your own code (such as STLport for
                            improved error checking). But "cool stuff" is just that, not
                            necessarily "required stuff". ;)

                            >
                            whereas
                            std::string might or might not be safe depending on the compiler and
                            flags used. In real world code, we've found that this does matter and
                            we have defined our interfaces accordingly.
                            >
                            In the real world, we use std::string and std::vector without
                            problems, over a variety of compilers and systems.
                            More power to you. For us, we've had bad experiences doing this with
                            one particular third party library we have to use (customer
                            requirement, library is the industry standard). We make heavy use of
                            std::string, std::vector within modules, we just avoid making them
                            part of the exposed interface. It's a bit of a pain, but until the C++
                            standard defines an ABI all compilers must adhere to, we have little
                            choice. Unfortunately, my understanding is that this has been pushed
                            out beyond the next draft.

                            --
                            Computational Fluid Dynamics, CSIRO (CMIS)
                            Melbourne, Australia

                            Comment

                            • James Kanze

                              #15
                              Re: const char* vs string

                              On Jun 4, 1:23 pm, Craig Scott <audiofana...@g mail.comwrote:
                              Actually, it can also matter for C++ code. If you are using shared
                              libraries, then you need to be aware that the C++ standard does not
                              guarantee that std::string is safe to use anywhere in a shared
                              library's interface (it mentions absolutely nothing about shared
                              libraries at all).
                              Strictly speaking, that's true for int as well. If all you're
                              counting on is what the C++ standard says, then you can't count
                              on int working in a dynamically linked object either.
                              Fair enough.
                              But of course, we all count on a little bit more from time to
                              time:-).
                              This is frequently a surprise to many C++
                              developers, but Scott Meyers and others give this topic a good
                              treatment in their various books (sorry, I don't have them on hand at
                              the moment, but one of the Effective C++/STL books I think). In short,
                              unless you can guarantee that your code is being compiled with exactly
                              the same compiler version as the library you are calling and that you
                              are using exactly the same compiler flags, then the only types safe to
                              use in the shared library's interface are POD types and pointers (but
                              it would be potentially unsafe to dereference these pointers).
                              Not even that: you can't be sure at all about any struct, since
                              padding may depend on compiler options. For that matter, you
                              can't be sure about long---I've had the byte order of a long
                              change from one version of the compiler to the next, and you
                              certainly can't be sure about pointers, whose size depends on
                              compiler options.
                              Um, I believe I said exactly the same compiler version and flags. If
                              you use the same settings on the same compiler for the same platform,
                              you should get the same byte order, padding, pointer size, etc.
                              If you use the same settings on the same compiler for the same
                              platform, you also have the same version of the standard
                              library.

                              Different compilers make different guarantees with regards to
                              "binary compatibility", but if binary compatability is
                              guaranteed between the different options, versions, etc., then
                              there should be no problem with the standard library either. If
                              it's not, on the other hand, you're likely to have problems with
                              POD struct's, pointers and---it happened once to me---even
                              longs or double. The standard library is part of the compiler,
                              and is covered by the sane "binary compatability" guarantees as
                              the rest.
                              In practice, there will be a set of options you can play with,
                              over a set of versions of the compiler.
                              So for the original poster's question, const char* will always be
                              portable and is safe to use in a library interface,
                              Except when the size of a pointer depends on a compiler option
                              (the usual case today, where all of the platforms I know support
                              both 32 and 64 bit pointers).
                              Agreed. If you change a compiler option which causes a different
                              pointer size, you should expect things to explode. ;) I think the
                              main point is to know what compiler and flags were used to build the
                              shared library you want to use. It is then your responsibility to use
                              compatible flags for your own code.
                              In fact, you're never really portable. The library supplier
                              should specify the restrictions, but in general, using
                              std::string entails no more risk than using any other struct.
                              Unless different modules have their own memory heap (we have
                              encountered situations where some do).
                              As far as I know, that never occurs under Unix, and only if you
                              don't take the proper precautions under Windows. (On the other
                              hand, I'm not sure who has to take the precautions: the user, or
                              the supplier of the DLL.) But that's a larger problem: you
                              can't free memory in one DLL that was allocated in another. Not
                              using components from the standard library isn't enough to avoid
                              problems.
                              Then you run the risk of having
                              memory allocated in one module and then when you resize the string,
                              vector, etc in another module the memory needs to be freed in that
                              module and BOOM! Even if memory is always allocated/deallocated from
                              the one heap, having std::string, std::vector or any other container
                              in the interface prevents you from doing some cool stuff like use an
                              alternate STL implementation in your own code (such as STLport for
                              improved error checking). But "cool stuff" is just that, not
                              necessarily "required stuff". ;)
                              I'm very sceptical about swapping the standard library. It's
                              part of the compiler, and you never know how much knowledge of
                              its implementation is built into the compiler.
                              whereas
                              std::string might or might not be safe depending on the compiler and
                              flags used. In real world code, we've found that this does matter and
                              we have defined our interfaces accordingly.
                              In the real world, we use std::string and std::vector without
                              problems, over a variety of compilers and systems.
                              More power to you. For us, we've had bad experiences doing this with
                              one particular third party library we have to use (customer
                              requirement, library is the industry standard). We make heavy use of
                              std::string, std::vector within modules, we just avoid making them
                              part of the exposed interface. It's a bit of a pain, but until the C++
                              standard defines an ABI all compilers must adhere to, we have little
                              choice. Unfortunately, my understanding is that this has been pushed
                              out beyond the next draft.
                              The C++ standard will never define an ABI, since this is, by its
                              very nature, platform specific.

                              --
                              James Kanze (GABI Software) email:james.kan ze@gmail.com
                              Conseils en informatique orientée objet/
                              Beratung in objektorientier ter Datenverarbeitu ng
                              9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                              Comment

                              Working...