(FAQ details:) malloc(), void * and casts

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?utf-8?b?QXNiasO4cm4gU8OmYsO4?=

    #1

    (FAQ details:) malloc(), void * and casts


    This topic is a FAQ. But I have read the faq and spent a couple of
    hours browsing the group archives, and still have a few questions that
    I hope you can answer.

    My understanding is that recommended practice is to not cast the
    return value from malloc(). The rationale for this is that 1) the
    cast is not needed and 2) the cast may mask errors.

    I assume that the reason the cast is not needed has to do with the
    fact that the the pointer returned from malloc() is a void *, and not
    a pointer to any other type. (Is that correct?)

    If so, could you explain _why_ (and the details of why) casting the
    void pointer is not necessary?
    (For my naive eye, assigning a pointer of one type (void) to a pointer
    of another type (e.g. int) does not seem quite "correct".)

    I do have the spec (ISO 9899:1999) at my desk, but I am not familiar
    enough with it to find the answer to this one. So references to the
    spec, possibly along with some interpretation, would also be helpful.


    With kind regards
    Asbjørn Sæbø
  • Mark Bluemel

    #2
    Re: (FAQ details:) malloc(), void * and casts

    Asbjørn Sæbø wrote:
    My understanding is that recommended practice is to not cast the
    return value from malloc(). The rationale for this is that 1) the
    cast is not needed and 2) the cast may mask errors.
    That is so.
    I assume that the reason the cast is not needed has to do with the
    fact that the the pointer returned from malloc() is a void *, and not
    a pointer to any other type. (Is that correct?)
    Precisely.
    If so, could you explain _why_ (and the details of why) casting the
    void pointer is not necessary?
    Because according to the standard, pointer to void can be converted to
    and from any other object pointer type.
    (For my naive eye, assigning a pointer of one type (void) to a pointer
    of another type (e.g. int) does not seem quite "correct".)
    It's (part of) what the standard intended void * to be used for, as I
    understand it.
    I do have the spec (ISO 9899:1999) at my desk, but I am not familiar
    enough with it to find the answer to this one. So references to the
    spec, possibly along with some interpretation, would also be helpful.
    Section 6.3.2.3 is fairly clear, I think.

    Comment

    • =?utf-8?b?QXNiasO4cm4gU8OmYsO4?=

      #3
      Re: (FAQ details:) malloc(), void * and casts

      Mark Bluemel <mark_bluemel@p obox.comwrites:
      Asbjørn Sæbø wrote:
      >
      [Why it it not necessary to cast the return value from malloc() ]
      If so, could you explain _why_ (and the details of why) casting the
      void pointer is not necessary?
      >
      Because according to the standard, pointer to void can be converted to
      and from any other object pointer type.
      [...]
      Section 6.3.2.3 is fairly clear, I think.
      "A pointer to void may be converted to or from a pointer to any
      incomplete or object type. [...]"

      And this conversion is implicit? And it is "kosher" in every way, and
      should not elicit any warnings ("diagnostics"? ) from the compiler?

      The reason I ask is that I have been told that at least the Lint we
      use at work will object to assigning a void* to e.g. an int *.

      Asbjørn


      Comment

      • Richard

        #4
        Re: (FAQ details:) malloc(), void * and casts

        Asbjørn Sæbø <invalid@invali d.invalidwrites :
        This topic is a FAQ. But I have read the faq and spent a couple of
        hours browsing the group archives, and still have a few questions that
        I hope you can answer.
        >
        My understanding is that recommended practice is to not cast the
        return value from malloc(). The rationale for this is that 1) the
        cast is not needed and 2) the cast may mask errors.
        >
        I assume that the reason the cast is not needed has to do with the
        fact that the the pointer returned from malloc() is a void *, and not
        a pointer to any other type. (Is that correct?)
        >
        If so, could you explain _why_ (and the details of why) casting the
        void pointer is not necessary?
        (For my naive eye, assigning a pointer of one type (void) to a pointer
        of another type (e.g. int) does not seem quite "correct".)
        It isn't. And so the C language does the conversion for you using an
        implicit conversion. (I think thats the terminology...)

        http://www.stanford.edu/~blp/writing...lloc-cast.html

        >
        I do have the spec (ISO 9899:1999) at my desk, but I am not familiar
        enough with it to find the answer to this one. So references to the
        spec, possibly along with some interpretation, would also be helpful.
        >
        >
        With kind regards
        Asbjørn Sæbø

        Comment

        • Mark Bluemel

          #5
          Re: (FAQ details:) malloc(), void * and casts

          Asbjørn Sæbø wrote:
          Mark Bluemel <mark_bluemel@p obox.comwrites:
          >
          >Asbjørn Sæbø wrote:
          >>
          >[Why it it not necessary to cast the return value from malloc() ]
          >
          >>If so, could you explain _why_ (and the details of why) casting the
          >>void pointer is not necessary?
          >Because according to the standard, pointer to void can be converted to
          >and from any other object pointer type.
          >[...]
          >
          >Section 6.3.2.3 is fairly clear, I think.
          >
          "A pointer to void may be converted to or from a pointer to any
          incomplete or object type. [...]"
          >
          And this conversion is implicit?
          If by that you mean you can simply assign a void * to an int *, yes.
          And it is "kosher" in every way, and
          should not elicit any warnings ("diagnostics"? ) from the compiler?
          Compilers can choose to warn you about just about anything, I believe.

          But such code is strictly compliant.
          The reason I ask is that I have been told that at least the Lint we
          use at work will object to assigning a void* to e.g. an int *.
          Then that lint is broken, IMHO. In ISO C (C++ is different), the direct
          assignment is, in your words, "kosher" and is to be preferred to
          casting, as casting can hide errors.

          I recently spent a significant amount of time chasing a such an error -
          lack of a prototype meant that the compiler took the return result of a
          function as "int" (32-bits), that was cast to "int *" (64-bits) and half
          the pointer was missing. Naturally the program crashed.

          Without the unnecessary cast, the error would have been picked up much
          earlier.

          Comment

          • Richard Tobin

            #6
            Re: (FAQ details:) malloc(), void * and casts

            In article <rgdr6iuxp77.fs f@ardbeg.nordic semi.no>,
            Asbjørn Sæbø <invalid@invali d.invalidwrote:
            >If so, could you explain _why_ (and the details of why) casting the
            >void pointer is not necessary?
            >(For my naive eye, assigning a pointer of one type (void) to a pointer
            >of another type (e.g. int) does not seem quite "correct".)
            The purpose of the void pointer type is to hold pointers that are
            really of another type. There's nothing you do with a void pointer
            itself except pass it around and convert it to other types.

            Converting between other pointer types on the other hand is unusual,
            something you want to think twice about. It's reasonable to have to
            be explicit about it if that's what you really want to do.

            -- Richard
            --
            "Considerat ion shall be given to the need for as many as 32 characters
            in some alphabets" - X3.4, 1963.

            Comment

            • Richard Tobin

              #7
              Re: (FAQ details:) malloc(), void * and casts

              In article <fhc8al$9kt$1@a ioe.org>,
              Mark Bluemel <mark_bluemel@p obox.comwrote:
              >If so, could you explain _why_ (and the details of why) casting the
              >void pointer is not necessary?
              >Because according to the standard, pointer to void can be converted to
              >and from any other object pointer type.
              This isn't sufficient explanation. The same is true of character
              pointer types, but you do need a cast there.
              >(For my naive eye, assigning a pointer of one type (void) to a pointer
              >of another type (e.g. int) does not seem quite "correct".)
              >It's (part of) what the standard intended void * to be used for, as I
              >understand it.
              This is better. Converting to and from void * isn't just legal, it's
              what you're meant to do.

              -- Richard
              --
              "Considerat ion shall be given to the need for as many as 32 characters
              in some alphabets" - X3.4, 1963.

              Comment

              • Keith Thompson

                #8
                Re: (FAQ details:) malloc(), void * and casts

                Mark Bluemel <mark_bluemel@p obox.comwrites:
                Asbjørn Sæbø wrote:
                [...]
                >If so, could you explain _why_ (and the details of why) casting the
                >void pointer is not necessary?
                >
                Because according to the standard, pointer to void can be converted to
                and from any other object pointer type.
                [...]
                Section 6.3.2.3 is fairly clear, I think.
                Yes, but that just says which conversions are allowed (and what they
                mean), not which ones can be done implicitly.

                6.5.16.1p1 describes the constraints for simple assignment, one of
                which is:

                one operand is a pointer to an object or incomplete type and the
                other is a pointer to a qualified or unqualified version of void,
                and the type pointed to by the left has all the qualifiers of the
                type pointed to by the right

                and paragraph 2 says:

                In simple assignment (=), the value of the right operand is
                converted to the type of the assignment expression and replaces
                the value stored in the object designated by the left operand.

                This is what allows a conversion (in either direction) between void*
                and another pointer type (other than a pointer-to-function type) to be
                performed implicitly.

                There are similar rules for initialization and argument passing.

                <OT>C++ has different rules.</OT>

                --
                Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                Looking for software development work in the San Diego area.
                "We must do something. This is something. Therefore, we must do this."
                -- Antony Jay and Jonathan Lynn, "Yes Minister"

                Comment

                • Paul Hsieh

                  #9
                  Re: (FAQ details:) malloc(), void * and casts

                  On Nov 13, 5:14 am, Asbjørn Sæbø <inva...@invali d.invalidwrote:
                  This topic is a FAQ. But I have read the faq and spent a couple of
                  hours browsing the group archives, and still have a few questions that
                  I hope you can answer.
                  >
                  My understanding is that recommended practice is to not cast the
                  return value from malloc(). The rationale for this is that 1) the
                  cast is not needed and 2) the cast may mask errors.
                  Right. As you can see 1) is not actually a rationale at all -- its
                  just a confirmation that it happens to be legal due to the original
                  design of C, and therefore possible. Its like recommending that you
                  eat a gallon of whip cream every day because its possible. And 2)
                  simply does not apply at all on modern compilers -- pretty much every
                  compiler I use will warn me if I fail to include <stdlib.hand yet
                  use malloc().

                  This "recommendation " does not have any further basis to it. It also
                  ignores the obvious counter argument that the cast is necessary to
                  make the same code compatible with C and C++ (a useful thing, that is
                  in common practice). Many C++ compilers have vastly superior warnings
                  and can commonly produce better code, so it very often pays to compile
                  your ANSI C code with a C++ compiler. C++ compilers, these days, are
                  better maintained than C compilers.
                  I assume that the reason the cast is not needed has to do with the
                  fact that the the pointer returned from malloc() is a void *, and not
                  a pointer to any other type. (Is that correct?)
                  Right. void * is automatically coercible to any data pointer type in
                  C. (It is not in C++, and requires explicit casting.)
                  If so, could you explain _why_ (and the details of why) casting the
                  void pointer is not necessary?
                  The standard happens to allow this. Its a legacy thing -- in the past
                  (before vendors supported the ANSI standard) some compilers used to
                  allow coercion of any pair of pointers.
                  (For my naive eye, assigning a pointer of one type (void) to a pointer
                  of another type (e.g. int) does not seem quite "correct".)
                  Well, one way or another the result starting from malloc is a void *
                  anyways. Casting it doesn't change the real result, it just forces
                  the compiler to copy pointers of one type into pointers of a different
                  type because that's just the way C is.

                  But, with very simple use of macros on top of malloc, its possible to
                  synchronize the size of what you are allocating with the type of what
                  you are allocating (arrays need some extra consideration) which allows
                  you to ignore ANSI C's "extra flexibility" and retain a type-safe
                  subset of the language without losing relevant functionality.
                  I do have the spec (ISO 9899:1999) at my desk, but I am not familiar
                  enough with it to find the answer to this one. So references to the
                  spec, possibly along with some interpretation, would also be helpful.
                  Just keep in mind that the C spec was written in the 80s for a
                  language designed in the 70s by hackers borrowing from other languages
                  who were just throwing it together on their way to designing UNIX. A
                  lot of the things in that spec are of a "historical " or "legacy"
                  nature.

                  --
                  Paul Hsieh
                  Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.



                  Comment

                  • CBFalconer

                    #10
                    Re: (FAQ details:) malloc(), void * and casts

                    Paul Hsieh wrote:
                    Asbjørn Sæbø <inva...@invali d.invalidwrote:
                    >
                    >This topic is a FAQ. But I have read the faq and spent a couple
                    >of hours browsing the group archives, and still have a few
                    >questions that I hope you can answer.
                    >>
                    >My understanding is that recommended practice is to not cast the
                    >return value from malloc(). The rationale for this is that 1)
                    >the cast is not needed and 2) the cast may mask errors.
                    >
                    Right. As you can see 1) is not actually a rationale at all --
                    its just a confirmation that it happens to be legal due to the
                    original design of C, and therefore possible. Its like
                    recommending that you eat a gallon of whip cream every day
                    because its possible. And 2) simply does not apply at all on
                    modern compilers -- pretty much every compiler I use will warn
                    me if I fail to include <stdlib.hand yet use malloc().
                    Just a quick reply to warn newbies that this Hsieh post is utter
                    nonsense. Compilers should not warn when a cast is present,
                    because the cast says "I know what I am doing, so shut up". Also,
                    C is not C++. The languages are different, have different rules,
                    and should be treated differently.

                    --
                    Chuck F (cbfalconer at maineline dot net)
                    <http://cbfalconer.home .att.net>
                    Try the download section.


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

                    Comment

                    • Lorenzo Villari

                      #11
                      Re: (FAQ details:) malloc(), void * and casts

                      "Paul Hsieh" <websnarf@gmail .comha scritto nel messaggio
                      news:1195004816 .781719.232340@ v23g2000prn.goo glegroups.com.. .
                      And 2) simply does not apply at all on modern compilers -- pretty much
                      every compiler I use will warn me if I fail to include <stdlib.hand yet
                      use malloc().
                      Yes. In fact I've always wondered why some people continue to say that...
                      Many C++ compilers have vastly superior warnings
                      and can commonly produce better code, so it very often pays to compile
                      your ANSI C code with a C++ compiler. C++ compilers, these days, are
                      better maintained than C compilers.
                      Ok for the warnings but:

                      1) Can you give me one example of better code? That would be
                      interesting...

                      2) What do you mean by "mantained" . Maybe that we have fewer C compilers
                      than C++ ones? If this is what you meant, I won't be too happy about
                      that
                      Just keep in mind that the C spec was written in the 80s for a
                      language designed in the 70s by hackers borrowing from other languages
                      who were just throwing it together on their way to designing UNIX. A
                      lot of the things in that spec are of a "historical " or "legacy"
                      nature.
                      Quite illuminating...



                      Comment

                      • Julienne Walker

                        #12
                        Re: (FAQ details:) malloc(), void * and casts

                        On Nov 13, 8:46 pm, Paul Hsieh <websn...@gmail .comwrote:
                        On Nov 13, 5:14 am, Asbjørn Sæbø <inva...@invali d.invalidwrote:
                        >
                        This topic is a FAQ. But I have read the faq and spent a couple of
                        hours browsing the group archives, and still have a few questions that
                        I hope you can answer.
                        >
                        My understanding is that recommended practice is to not cast the
                        return value from malloc(). The rationale for this is that 1) the
                        cast is not needed and 2) the cast may mask errors.
                        >
                        Right. As you can see 1) is not actually a rationale at all -- its
                        just a confirmation that it happens to be legal due to the original
                        design of C, and therefore possible. Its like recommending that you
                        eat a gallon of whip cream every day because its possible.
                        Actually, it's quite a good rationale when taken with the very solid
                        advice that casts should be avoided whenever possible (which, I'll
                        add, is an equally strong recommendation in C++, since you're trying
                        to advocate C++ compatibility). Why add a redundant cast when it's
                        completely unnecessary? When someone advocates casting malloc, I'm
                        reminded of the following abomination:

                        (void)printf( "blahblahblah\n " );
                        And 2) simply does not apply at all on modern compilers -- pretty
                        much every compiler I use will warn me if I fail to include <stdlib.h>
                        and yet use malloc().
                        It silences at least one warning on all of my 'modern' compilers.
                        Personally, I'd rather have the warning than not, so I don't cast when
                        I can avoid it. Wise programmers don't hide warnings without extremely
                        good reason.
                        This "recommendation " does not have any further basis to it. It also
                        ignores the obvious counter argument that the cast is necessary to
                        make the same code compatible with C and C++ (a useful thing, that is
                        in common practice). Many C++ compilers have vastly superior warnings
                        and can commonly produce better code, so it very often pays to compile
                        your ANSI C code with a C++ compiler. C++ compilers, these days, are
                        better maintained than C compilers.
                        If you want C++, use C++. Trying to write C++ compatible C, while
                        disturbingly common, is also surprisingly difficult to get right. The
                        counter argument has less of a foundation than you claim the original
                        argument to have.

                        Yes, it is useful to write C++ compatible C. But only occasionally. I
                        see this as an exception to the rule and not a reason to ignore the
                        rule.
                        I do have the spec (ISO 9899:1999) at my desk, but I am not familiar
                        enough with it to find the answer to this one. So references to the
                        spec, possibly along with some interpretation, would also be helpful.
                        >
                        Just keep in mind that the C spec was written in the 80s for a
                        language designed in the 70s by hackers borrowing from other languages
                        who were just throwing it together on their way to designing UNIX. A
                        lot of the things in that spec are of a "historical " or "legacy"
                        nature.
                        ...


                        -Jul

                        Comment

                        • Paul Hsieh

                          #13
                          Re: (FAQ details:) malloc(), void * and casts

                          On Nov 19, 7:38 am, "Lorenzo Villari" <vll...@tiscali .itwrote:
                          "Paul Hsieh" <websn...@gmail .comha scritto nel
                          And 2) simply does not apply at all on modern compilers -- pretty much
                          every compiler I use will warn me if I fail to include <stdlib.hand yet
                          use malloc().
                          >
                          Yes. In fact I've always wondered why some people continue to say that...
                          Because they have an agenda to push. There is literally no
                          justification for this recommendation, except as a way of enforcing a
                          needless artificial incompatibility with C++.
                          Many C++ compilers have vastly superior warnings
                          and can commonly produce better code, so it very often pays to compile
                          your ANSI C code with a C++ compiler. C++ compilers, these days, are
                          better maintained than C compilers.
                          >
                          Ok for the warnings but:
                          >
                          1) Can you give me one example of better code? That would be
                          interesting...
                          Urg. I shouldn't have put myself out there, now I can't dig up a
                          concrete example. I am an avid user of the WATCOM C/C++ compilers.
                          They decided to supply their C and C++ solutions as two separate
                          compilers and at various times they have clearly put more effort into
                          their C++ optimizer. I had some benchmarks somewhere long ago that
                          demonstrated this.
                          2) What do you mean by "mantained" . Maybe that we have fewer C compilers
                          than C++ ones? If this is what you meant, I won't be too happy about
                          that
                          Well C compilers certainly still exist, and some vendors, like
                          Microsoft, continue to use a single compiler that compiles both
                          languages. But GNU, and Watcom have clearly taken the two compiler
                          approach (but in different ways; GNU uses a common back end, at least
                          for now.)

                          --
                          Paul Hsieh
                          Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.


                          Comment

                          • Paul Hsieh

                            #14
                            Re: (FAQ details:) malloc(), void * and casts

                            On Nov 19, 10:49 am, Julienne Walker <happyfro...@ho tmail.comwrote:
                            On Nov 13, 8:46 pm, Paul Hsieh <websn...@gmail .comwrote:
                            On Nov 13, 5:14 am, Asbjørn Sæbø <inva...@invali d.invalidwrote:
                            >
                            This topic is a FAQ. But I have read the faq and spent a couple of
                            hours browsing the group archives, and still have a few questions that
                            I hope you can answer.
                            >
                            My understanding is that recommended practice is to not cast the
                            return value from malloc(). The rationale for this is that 1) the
                            cast is not needed and 2) the cast may mask errors.
                            >
                            Right. As you can see 1) is not actually a rationale at all -- its
                            just a confirmation that it happens to be legal due to the original
                            design of C, and therefore possible. Its like recommending that you
                            eat a gallon of whip cream every day because its possible.
                            >
                            Actually, it's quite a good rationale when taken with the very solid
                            advice that casts should be avoided whenever possible (which, I'll
                            add, is an equally strong recommendation in C++, since you're trying
                            to advocate C++ compatibility).
                            Without the cast, the code is erroneous and will not compiler on a
                            correct C++ compiler. In this case the casting is not redundant, as
                            it specifically create a type check which is realistically helpful in
                            "cut-paste" situations.
                            [...] Why add a redundant cast when it's
                            completely unnecessary? When someone advocates casting malloc, I'm
                            reminded of the following abomination:
                            >
                            (void)printf( "blahblahblah\n " );
                            The two have nothing to do with each other. No type checking is
                            happening here, and there is no functional purpose for it.
                            And 2) simply does not apply at all on modern compilers -- pretty
                            much every compiler I use will warn me if I fail to include <stdlib.h>
                            and yet use malloc().
                            >
                            It silences at least one warning on all of my 'modern' compilers.
                            But it is an extraneous warning. You are going to get the warning for
                            using a function without a prototype or implementation anyways (if you
                            drop the inclusion of stdlib.h) -- that really what the problem is
                            anyways, not a pointer/int type mismatch.
                            Personally, I'd rather have the warning than not, so I don't cast when
                            I can avoid it. Wise programmers don't hide warnings without extremely
                            good reason.
                            Wise or not, redundant and misleading warnings for an error you
                            already have a warning for is not going to help one iota.
                            This "recommendation " does not have any further basis to it. It also
                            ignores the obvious counter argument that the cast is necessary to
                            make the same code compatible with C and C++ (a useful thing, that is
                            in common practice). Many C++ compilers have vastly superior warnings
                            and can commonly produce better code, so it very often pays to compile
                            your ANSI C code with a C++ compiler. C++ compilers, these days, are
                            better maintained than C compilers.
                            >
                            If you want C++, use C++. Trying to write C++ compatible C, while
                            disturbingly common, is also surprisingly difficult to get right.
                            What are you talking about? I write code like that, pretty much
                            exclusively nowadays. Its not challenging in the least. Certainly
                            consumers of the Better String Library appreciate it.
                            [...] The
                            counter argument has less of a foundation than you claim the original
                            argument to have.
                            The original justification is blatantly false. My justification
                            corresponds to real issues, and real code.

                            --
                            Paul Hsieh
                            Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.


                            Comment

                            • CJ

                              #15
                              Re: (FAQ details:) malloc(), void * and casts

                              On 13 Nov 2007 at 13:20, Mark Bluemel wrote:
                              Asbjørn Sæbø wrote:
                              >
                              >My understanding is that recommended practice is to not cast the
                              >return value from malloc(). The rationale for this is that 1) the
                              >cast is not needed and 2) the cast may mask errors.
                              >
                              That is so.
                              >
                              >I assume that the reason the cast is not needed has to do with the
                              >fact that the the pointer returned from malloc() is a void *, and not
                              >a pointer to any other type. (Is that correct?)
                              >
                              Precisely.
                              >
                              >If so, could you explain _why_ (and the details of why) casting the
                              >void pointer is not necessary?
                              >
                              Because according to the standard, pointer to void can be converted to
                              and from any other object pointer type.
                              In many older implementations of the standard library, malloc is defined
                              to return a char * rather than a void *, so including the cast makes
                              your program more portable.

                              Comment

                              Working...