Returning a pointer to a constant string

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?iso-8859-1?q?Santiago_Urue=F1a?=

    #1

    Returning a pointer to a constant string

    Hi,

    I tried to return a pointer to a constant string, but the compiler
    gives the following warning if a cast is not used:

    warning: assignment from incompatible pointer type

    This is the code:


    const char msg[] = "Test message";

    const char *message(void) {
    return msg;
    }

    int main(void){
    const char * str;

    str = (const char *)message;
    str = (char *)message;
    str = message; /* GCC warning! */

    str = (const char *)msg;
    str = (char *)msg;
    str = msg;

    return 0;
    }

    Oddly, GCC only gives the warning if no cast is used, but it doesn't
    complain if the cast discards the const qualifier. Is this behavior
    OK? I'm using GCC 4.1.2. Thanks!

    Best regards,

    Santi

  • Walter Roberson

    #2
    Re: Returning a pointer to a constant string

    In article <1190068695.241 389.292540@g4g2 000hsf.googlegr oups.com>,
    =?iso-8859-1?q?Santiago_Ur ue=F1a?= <suruena@gmail. comwrote:
    >I tried to return a pointer to a constant string, but the compiler
    >gives the following warning if a cast is not used:
    warning: assignment from incompatible pointer type
    >This is the code:
    >const char msg[] = "Test message";
    >const char *message(void) {
    return msg;
    >}
    Pay close attention to the placement of the const qualifiers.

    const char msg[] says that msg[someindex] will be a const char

    const char *message(void)

    says that message will return a pointer to a char and that the
    pointer is constant. (I think. I'm not -positive-. I haven't had
    much occasion to use const.)
    --
    All is vanity. -- Ecclesiastes

    Comment

    • JimS

      #3
      Re: Returning a pointer to a constant string

      On Mon, 17 Sep 2007 15:38:15 -0700, Santiago Urueña
      <suruena@gmail. comwrote:
      >Hi,
      >
      >I tried to return a pointer to a constant string, but the compiler
      >gives the following warning if a cast is not used:
      >
      warning: assignment from incompatible pointer type
      >
      >This is the code:
      >
      >
      >const char msg[] = "Test message";
      >
      >const char *message(void) {
      return msg;
      >}
      >
      >int main(void){
      const char * str;
      >
      str = (const char *)message;
      str = (char *)message;
      str = message; /* GCC warning! */
      message is a pointer to a function returning const char *. The
      previous two casts are covering up a gratuitous mistake!

      Jim

      Comment

      • =?iso-8859-1?q?Santiago_Urue=F1a?=

        #4
        Re: Returning a pointer to a constant string

        str = (const char *)message;
        str = (char *)message;
        str = message; /* GCC warning! */
        >
        message is a pointer to a function returning const char *. The
        previous two casts are covering up a gratuitous mistake!
        >
        You are right! Silly me.

        Anyway, the compiler doesn't give any warning even if the qualifier is
        discarded by the cast:

        str = (const char *)message();
        str = (char *)message(); /* No warning! */
        str = message();

        Is this OK?

        Thanks again.

        Santi

        Comment

        • =?iso-8859-1?q?Santiago_Urue=F1a?=

          #5
          Re: Returning a pointer to a constant string

          Anyway, the compiler doesn't give any warning even if the qualifier is
          discarded by the cast:
          >
          str = (const char *)message();
          str = (char *)message(); /* No warning! */
          str = message();
          >
          Is this OK?
          >
          After thinking a little more about this, I think I have the answer:
          the compiler shouldn't give a warning because a pointer to a non-const
          object is being assigned to a pointer to a const object, and this is
          totally OK because (anyway you cannot modify the object via the 'str'
          pointer).

          Thanks

          Comment

          • Keith Thompson

            #6
            Re: Returning a pointer to a constant string

            Santiago Urueña <suruena@gmail. comwrites:
            str = (const char *)message;
            str = (char *)message;
            str = message; /* GCC warning! */
            >>
            >message is a pointer to a function returning const char *. The
            >previous two casts are covering up a gratuitous mistake!
            >>
            You are right! Silly me.
            >
            Anyway, the compiler doesn't give any warning even if the qualifier is
            discarded by the cast:
            >
            str = (const char *)message();
            str = (char *)message(); /* No warning! */
            str = message();
            >
            Is this OK?
            Please leave attribution lines in place for quoted text (i.e., lines
            like "So-and-so <foo@bar.comwri tes:"). They make it easier to
            follow the conversation, and it's just polite to credit people for
            their words.

            A cast specifies a type conversion, but what it *really* does is tell
            the compiler "I know exactly what I'm doing, don't bother me with
            warnings". Because of that property, almost all casts should be
            viewed with suspicion. Adding a cast for the sole purpose of
            silencing a compiler warning is almost always a mistake; the correct
            solution is usually to fix the code so the cast isn't required, either
            by arranging for things to be of the desired type in the first place
            or by using types that are converted implicitly.

            One of the few cases where a cast is necessary is for some arguments
            to variadic functions like printf(). For non-variadic functions, the
            compiler knows the required type and is able to generate an implicit
            conversion if necessary. For a variadic function, the compiler
            doesn't necessarily have this information, so you have to give it some
            help.

            --
            Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
            San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
            "We must do something. This is something. Therefore, we must do this."
            -- Antony Jay and Jonathan Lynn, "Yes Minister"

            Comment

            • CBFalconer

              #7
              Re: Returning a pointer to a constant string

              Santiago Urueña wrote:
              >
              I tried to return a pointer to a constant string, but the compiler
              gives the following warning if a cast is not used:
              >
              warning: assignment from incompatible pointer type
              >
              This is the code:
              >
              const char msg[] = "Test message";
              >
              const char *message(void) {
              return msg;
              }
              msg is an array. &msg is a pointer to msg.

              --
              Chuck F (cbfalconer at maineline dot net)
              Available for consulting/temporary embedded and systems.
              <http://cbfalconer.home .att.net>


              --
              Posted via a free Usenet account from http://www.teranews.com

              Comment

              • Martin Ambuhl

                #8
                Re: Returning a pointer to a constant string

                Santiago Urueña wrote:
                Hi,
                >
                I tried to return a pointer to a constant string, but the compiler
                gives the following warning if a cast is not used:
                >
                warning: assignment from incompatible pointer type
                >
                This is the code:
                >
                >
                const char msg[] = "Test message";
                >
                const char *message(void) {
                return msg;
                }
                >
                int main(void){
                const char * str;
                >
                str = (const char *)message;
                str = (char *)message;
                str = message; /* GCC warning! */
                >
                str = (const char *)msg;
                str = (char *)msg;
                str = msg;
                >
                return 0;
                }
                const char msg[] = "Test message";
                /* msg (above) is a character array, but message is a function */
                const char *message(void)
                {
                return msg;
                }

                int main(void)
                {
                const char *str;
                str = message(); /* notice parenthesis; message is not a
                pointer-to-char but a function
                returning a (const) pointer-to-char */
                str = msg;
                return 0;
                }

                Comment

                • anders

                  #9
                  Re: Returning a pointer to a constant string

                  Hmm as i see it
                  one type is a char [] and one is char *
                  that way
                  str = (char *)message();
                  works.
                  // Anders


                  On 18 Sep, 01:49, CBFalconer <cbfalco...@yah oo.comwrote:
                  Santiago Urueña wrote:
                  >
                  I tried to return a pointer to a constant string, but the compiler
                  gives the following warning if a cast is not used:
                  >
                  warning: assignment from incompatible pointer type
                  >
                  This is the code:
                  >
                  const char msg[] = "Test message";
                  >
                  const char *message(void) {
                  return msg;
                  }
                  >
                  msg is an array. &msg is a pointer to msg.
                  >
                  --
                  Chuck F (cbfalconer at maineline dot net)
                  Available for consulting/temporary embedded and systems.
                  <http://cbfalconer.home .att.net>
                  >
                  --
                  Posted via a free Usenet account fromhttp://www.teranews.co m

                  Comment

                  • Charlie Gordon

                    #10
                    Re: Returning a pointer to a constant string

                    "Walter Roberson" <roberson@ibd.n rc-cnrc.gc.caa écrit dans le message de
                    news: fcn02v$2j9$1@ca nopus.cc.umanit oba.ca...
                    In article <1190068695.241 389.292540@g4g2 000hsf.googlegr oups.com>,
                    =?iso-8859-1?q?Santiago_Ur ue=F1a?= <suruena@gmail. comwrote:
                    >
                    >>I tried to return a pointer to a constant string, but the compiler
                    >>gives the following warning if a cast is not used:
                    >
                    > warning: assignment from incompatible pointer type
                    >
                    >>This is the code:
                    >
                    >>const char msg[] = "Test message";
                    >
                    >>const char *message(void) {
                    > return msg;
                    >>}
                    >
                    Pay close attention to the placement of the const qualifiers.
                    >
                    const char msg[] says that msg[someindex] will be a const char
                    correct. It could also be written char const msg[].
                    const char *message(void)
                    >
                    says that message will return a pointer to a char and that the
                    pointer is constant.
                    No, such a pointer would be defined as char * const p; and it makes no sense
                    as a return value for a function.
                    (I think. I'm not -positive-. I haven't had much occasion to use const.)
                    It shows!
                    Please don't post misleading answers on subjects you know you don't master.

                    --
                    Chqrlie.


                    Comment

                    • Charlie Gordon

                      #11
                      Re: Returning a pointer to a constant string

                      "Santiago Urueña" <suruena@gmail. coma écrit dans le message de news:
                      1190068695.2413 89.292540@g4g20 00...legro ups.com...
                      Hi,
                      >
                      I tried to return a pointer to a constant string, but the compiler
                      gives the following warning if a cast is not used:
                      >
                      warning: assignment from incompatible pointer type
                      >
                      This is the code:
                      >
                      >
                      const char msg[] = "Test message";
                      >
                      const char *message(void) {
                      return msg;
                      }
                      >
                      int main(void){
                      const char * str;
                      >
                      str = (const char *)message;
                      str = (char *)message;
                      str = message; /* GCC warning! */
                      >
                      str = (const char *)msg;
                      str = (char *)msg;
                      str = msg;
                      >
                      return 0;
                      }
                      >
                      Oddly, GCC only gives the warning if no cast is used, but it doesn't
                      complain if the cast discards the const qualifier. Is this behavior
                      OK? I'm using GCC 4.1.2. Thanks!
                      Well well, gcc gives you a warning and you don't read it.
                      "assignment from incompatible pointer type" is not about the const
                      qualifier being discarded... after all str is a const char *, no const
                      qualifier is discard by these assignments, as the rest of the code shows.

                      The problem is much worse, and a good example of why casts must be avoided.
                      You are attempting to store a pointer to the function 'message', not the
                      result of an invocation because you missed the ().

                      str = message; is correctly diagnosed as an assignment from incompatible
                      pointer types.

                      By casting message to (char*) or (const char*), you are effectively telling
                      the compiler to shut up because you presumably know what you are doing (for
                      instance, you are trying to disassemble the function and you know the
                      respective representations of function pointers and char pointers are
                      compatible on your target). gcc respects that and does not complain.

                      But you are wrong. Your code invokes undefined behaviour.

                      Consequently: do not use casts. Turn extra gcc warnings on so it complains
                      about suspicious casts and a flew of other things.

                      --
                      Chqrlie.


                      Comment

                      • Charlie Gordon

                        #12
                        Re: Returning a pointer to a constant string

                        "CBFalconer " <cbfalconer@yah oo.coma écrit dans le message de news:
                        46EF127E.E35C44 72@yahoo.com...
                        Santiago Urueña wrote:
                        >>
                        >I tried to return a pointer to a constant string, but the compiler
                        >gives the following warning if a cast is not used:
                        >>
                        > warning: assignment from incompatible pointer type
                        >>
                        >This is the code:
                        >>
                        >const char msg[] = "Test message";
                        >>
                        >const char *message(void) {
                        > return msg;
                        >}
                        >
                        msg is an array. &msg is a pointer to msg.
                        But message returns a pointer to char, correctly constructed by 'return
                        msg;' or 'return &msg[0];'.

                        Returning &msg here would be abusing the rules.

                        --
                        Chqrlie.


                        Comment

                        • =?iso-8859-1?q?Santiago_Urue=F1a?=

                          #13
                          Re: Returning a pointer to a constant string

                          On 18 sep, 12:48, "Charlie Gordon" <n...@chqrlie.o rgwrote:
                          "Santiago Urueña" <suru...@gmail. coma écrit dans le message de news:
                          1190068695.2413 89.292...@g4g20 00hsf.googlegro ups.com...
                          >
                          >
                          >
                          Hi,
                          >
                          I tried to return a pointer to a constant string, but the compiler
                          gives the following warning if a cast is not used:
                          >
                          warning: assignment from incompatible pointer type
                          >
                          This is the code:
                          >
                          const char msg[] = "Test message";
                          >
                          const char *message(void) {
                          return msg;
                          }
                          >
                          int main(void){
                          const char * str;
                          >
                          str = (const char *)message;
                          str = (char *)message;
                          str = message; /* GCC warning! */
                          >
                          str = (const char *)msg;
                          str = (char *)msg;
                          str = msg;
                          >
                          return 0;
                          }
                          >
                          Oddly, GCC only gives the warning if no cast is used, but it doesn't
                          complain if the cast discards the const qualifier. Is this behavior
                          OK? I'm using GCC 4.1.2. Thanks!
                          >
                          Well well, gcc gives you a warning and you don't read it.
                          "assignment from incompatible pointer type" is not about the const
                          qualifier being discarded... after all str is a const char *, no const
                          qualifier is discard by these assignments, as the rest of the code shows.
                          >
                          The problem is much worse, and a good example of why casts must be avoided.
                          You are attempting to store a pointer to the function 'message', not the
                          result of an invocation because you missed the ().
                          >
                          str = message; is correctly diagnosed as an assignment from incompatible
                          pointer types.
                          >
                          By casting message to (char*) or (const char*), you are effectively telling
                          the compiler to shut up because you presumably know what you are doing (for
                          instance, you are trying to disassemble the function and you know the
                          respective representations of function pointers and char pointers are
                          compatible on your target). gcc respects that and does not complain.
                          >
                          But you are wrong. Your code invokes undefined behaviour.
                          >
                          Consequently: do not use casts. Turn extra gcc warnings on so it complains
                          about suspicious casts and a flew of other things.
                          >
                          Thank you very much for all your responses. Of course I see the
                          problem now, it seems I was too asleep for not seeing that silly
                          mistake.

                          I always use -Wall and -Wextra until all warnings are corrected. I'm
                          of those persons that believe that the compiler usually knows much
                          better, I don't really know why in this case the message seemed to me
                          a possible compiler bug.

                          Keith, Thanks for the suggestion about variadic functions, it's always
                          good to know tips like that. I don't usually use casts neither,
                          specially from now on... :-)

                          Best regards,

                          Comment

                          • =?iso-8859-1?q?Santiago_Urue=F1a?=

                            #14
                            Re: Returning a pointer to a constant string

                            On 18 sep, 01:49, CBFalconer <cbfalco...@yah oo.comwrote:
                            Santiago Urueña wrote:
                            >
                            I tried to return a pointer to a constant string, but the compiler
                            gives the following warning if a cast is not used:
                            >
                            warning: assignment from incompatible pointer type
                            >
                            This is the code:
                            >
                            const char msg[] = "Test message";
                            >
                            const char *message(void) {
                            return msg;
                            }
                            >
                            msg is an array. &msg is a pointer to msg.
                            >
                            I'm not a language lawyer, but the & operator returns the _address_ of
                            an object, not the pointer. But in this case 'msg' is directly the
                            address of the array.

                            I declared 'msg' as 'const char msg[] = "...";' and not as 'const char
                            *const msg = "...";' because in this case there is no need to reserve
                            memory for a pointer to the string, but just to the string itself.

                            Best regards,

                            Santi

                            Comment

                            • Keith Thompson

                              #15
                              Re: Returning a pointer to a constant string

                              Santiago Urueña <suruena@gmail. comwrites:
                              On 18 sep, 01:49, CBFalconer <cbfalco...@yah oo.comwrote:
                              >Santiago Urueña wrote:
                              I tried to return a pointer to a constant string, but the compiler
                              gives the following warning if a cast is not used:
                              >>
                              warning: assignment from incompatible pointer type
                              >>
                              This is the code:
                              >>
                              const char msg[] = "Test message";
                              >>
                              const char *message(void) {
                              return msg;
                              }
                              >>
                              >msg is an array. &msg is a pointer to msg.
                              >>
                              I'm not a language lawyer, but the & operator returns the _address_ of
                              an object, not the pointer. But in this case 'msg' is directly the
                              address of the array.
                              Given an object obj, the phrases "a pointer to obj" and "the address
                              of obj" are synonymous.

                              Since msg is declared as an array, the expression '&msg' is the
                              address *of the array*, whereas the expression 'msg' (in most
                              contexts) yields the address of the arrsy's first element, the same as
                              '&msg[0]'.

                              [...]

                              Section 6 of the comp.lang.c FAQ is an excellent resource.

                              There's a program called "cdecl" that you might also find useful (if
                              you can find and install it).

                              --
                              Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                              San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
                              "We must do something. This is something. Therefore, we must do this."
                              -- Antony Jay and Jonathan Lynn, "Yes Minister"

                              Comment

                              Working...