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

Discussion in 'C Programming' started by =?utf-8?b?QXNiasO4cm4gU8OmYsO4?=, Nov 13, 2007.

  1. 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ø
     
    =?utf-8?b?QXNiasO4cm4gU8OmYsO4?=, Nov 13, 2007
    #1
    1. Advertising

  2. =?utf-8?b?QXNiasO4cm4gU8OmYsO4?=

    Mark Bluemel Guest

    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.
     
    Mark Bluemel, Nov 13, 2007
    #2
    1. Advertising

  3. In article <>,
    Asbjørn Sæbø <> wrote:

    >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
    --
    "Consideration shall be given to the need for as many as 32 characters
    in some alphabets" - X3.4, 1963.
     
    Richard Tobin, Nov 13, 2007
    #3
  4. In article <fhc8al$9kt$>,
    Mark Bluemel <> 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.


    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
    --
    "Consideration shall be given to the need for as many as 32 characters
    in some alphabets" - X3.4, 1963.
     
    Richard Tobin, Nov 13, 2007
    #4
  5. =?utf-8?b?QXNiasO4cm4gU8OmYsO4?=

    Richard Guest

    Asbjørn Sæbø <> writes:

    > 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/writings/clc/malloc-cast.html
    http://www.cpax.org.uk/prg/writings/casting.php

    >
    > 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ø
     
    Richard, Nov 13, 2007
    #5
  6. Mark Bluemel <> writes:

    > 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
     
    =?utf-8?b?QXNiasO4cm4gU8OmYsO4?=, Nov 13, 2007
    #6
  7. =?utf-8?b?QXNiasO4cm4gU8OmYsO4?=

    Mark Bluemel Guest

    Asbjørn Sæbø wrote:
    > Mark Bluemel <> writes:
    >
    >> 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.
     
    Mark Bluemel, Nov 13, 2007
    #7
  8. Mark Bluemel <> writes:
    > 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_Keith) <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"
     
    Keith Thompson, Nov 13, 2007
    #8
  9. =?utf-8?b?QXNiasO4cm4gU8OmYsO4?=

    Paul Hsieh Guest

    On Nov 13, 5:14 am, Asbjørn Sæbø <> wrote:
    > 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.h> and 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
    http://www.pobox.com/~qed/
    http://bstring.sf.net/
     
    Paul Hsieh, Nov 14, 2007
    #9
  10. =?utf-8?b?QXNiasO4cm4gU8OmYsO4?=

    CBFalconer Guest

    Paul Hsieh wrote:
    > Asbjørn Sæbø <> wrote:
    >
    >> 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.h> and 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
     
    CBFalconer, Nov 14, 2007
    #10
  11. Mark Bluemel <> wrote:
    > Asbjørn Sæbø wrote:
    > > Mark Bluemel <> writes:
    > > > Asbjørn Sæbø wrote:
    > > > > ...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,


    There are exceptions. For instance...

    int *ip; /* uninitialised */
    void *vp = ip; /* undefined behaviour */

    The conversion is implied, but it needn't be valid for
    particular circumstances.

    Another example is...

    int i;
    int *ip = &i;
    void *vp = ip; /* fine! */
    long *lp = vp; /* potential ub */

    Again, the conversions are implicit, but the standard
    does not guarantee that the last conversion will
    succeed on all implementations. Even on implementations
    where the conversion does succeed, the standard does
    not guarantee that lp will actually point to ip.

    The conversion is not about converting void pointers
    arbitrarily, but rather conversions from and _back_ to
    the original type and (equivalent) value.

    > > and should not elicit any warnings ("diagnostics"?)
    > > from the compiler?


    Most implementations of C talk about errors and warnings,
    where an error stops compilation (or linking), and a
    warning doesn't.

    The standard talks of diagnostics, some of which are
    required. [Only one required diagnostic need actually
    be issued.]

    There is no isomorphism between these two concepts. Indeed,
    most implementations have mixtures, and all combinations
    appear:

    Standard Implementation Example (on some systems)
    Diagnostic Alert

    required warning int *ip = 0xFFFC;

    required error int int i;

    not required warning while (*s = *p)

    not required error unresolved external identifier

    Notice that a cast in the first version will not change
    the raw semantics, though it will likely remove the warning.

    > Compilers can choose to warn you about just about anything,
    > I believe.
    >
    > But such code is strictly compliant.


    There are still caveats that apply to expressions, even
    if the conversion is defined.

    <snip>
    > 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.


    But the _root_ cause was the lack of required prototype
    within C. C99 doesn't quite go that far, but it does
    require a declaration. As a minimum, a function declaration
    includes a return type.

    You talk about not doing something merely because the
    standard allows it. Well, the fact that you're allowed to
    not cast the return of malloc, is also thought of as in-
    sufficient reason to do so. The (quite deliberate) type
    weakness of void pointers is one reason why some people
    deliberately cast malloc, even with the include header.

    Note that not casting can also conceil an error...

    int *p;
    p = (double *) malloc(sizeof *p);
    *p = 3.14159265358979; /* no bleebs, but wrong in context. */
    ...

    Of course, you won't find much understanding of (let
    alone support for) that in clc.

    My point is simply that different programmers have
    different styles. If you want to be able to understand
    a lot different code, you need to understand those
    styles, even if you yourself dislike or would never
    practice them.

    --
    Peter
     
    Peter Nilsson, Nov 14, 2007
    #11
  12. "Paul Hsieh" <> ha scritto nel messaggio
    news:...

    > 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().


    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...
     
    Lorenzo Villari, Nov 19, 2007
    #12
  13. On Nov 13, 8:46 pm, Paul Hsieh <> wrote:
    > On Nov 13, 5:14 am, Asbjørn Sæbø <> wrote:
    >
    > > 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
     
    Julienne Walker, Nov 19, 2007
    #13
  14. =?utf-8?b?QXNiasO4cm4gU8OmYsO4?=

    Paul Hsieh Guest

    On Nov 19, 7:38 am, "Lorenzo Villari" <> wrote:
    > "Paul Hsieh" <> ha 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.h> and 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
    http://www.pobox.com/~qed/
    http://bstring.sf.net/
     
    Paul Hsieh, Nov 19, 2007
    #14
  15. =?utf-8?b?QXNiasO4cm4gU8OmYsO4?=

    Paul Hsieh Guest

    On Nov 19, 10:49 am, Julienne Walker <> wrote:
    > On Nov 13, 8:46 pm, Paul Hsieh <> wrote:
    > > On Nov 13, 5:14 am, Asbjørn Sæbø <> wrote:

    >
    > > > 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
    http://www.pobox.com/~qed/
    http://bstring.sf.net/
     
    Paul Hsieh, Nov 19, 2007
    #15
  16. =?utf-8?b?QXNiasO4cm4gU8OmYsO4?=

    CJ Guest

    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.
     
    CJ, Nov 19, 2007
    #16
  17. =?utf-8?b?QXNiasO4cm4gU8OmYsO4?=

    Ian Collins Guest

    CJ wrote:
    > On 13 Nov 2007 at 13:20, Mark Bluemel wrote:


    >> 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.
    >

    That's a very rare corner case. Such libraries probably require
    malloc.h as well.

    --
    Ian Collins.
     
    Ian Collins, Nov 19, 2007
    #17
  18. =?utf-8?b?QXNiasO4cm4gU8OmYsO4?=

    Flash Gordon Guest

    Julienne Walker wrote, On 19/11/07 18:49:
    > On Nov 13, 8:46 pm, Paul Hsieh <> wrote:
    >> On Nov 13, 5:14 am, Asbjørn Sæbø <> wrote:
    >>
    >>> 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


    In fact, you should avoid all code that does not do something useful. It
    is more to read that does not help. Casting the result of malloc is one
    example where it can actually lead to people not spotting problems.

    It should be noted that those most likely not to enable warning about
    missing prototypes are also (in my opinion) those most likely to fail to
    include stdlib.h and add the cast to "fix" the warning. These people
    need to be broken of the habit of adding casts to fix warnings, and
    telling them it is OK to cast in the one instance is likely to slow the
    breaking of this habit.

    > (which, I'll
    > add, is an equally strong recommendation in C++, since you're trying
    > to advocate C++ compatibility).


    The best way to provide compatibility with C++ is normally to compile
    your C code as C and use the mechanisms

    > 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" );


    Agreed.

    >> 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.


    Also many compilers will not produce a warning about no prototype on
    there default warning levels but *will* provide a warning if there is
    stdlib.h has been forgotten and no cast is used.

    >> 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.


    Indeed. Some code will compile as C or C++ but behave differently
    depending on which language you compile it as.

    > 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.


    The only common exception is header files, and those will not in general
    include calls to malloc.

    >>> 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.


    Yes, C has a number of problems due to its legacy. However the changes
    that mean casting the value returned by malloc is not needed were quite
    deliberate not accidents of history.
    --
    Flash Gordon
     
    Flash Gordon, Nov 19, 2007
    #18
  19. Paul Hsieh wrote:
    > On Nov 19, 7:38 am, "Lorenzo Villari" <> wrote:
    >> "Paul Hsieh" <> ha 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.h> and 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++.

    [...]

    (Context: the issue here is casting or not casting the result of malloc().)

    Paul, regardless of the technical merits of your argument, your
    assertion that those of us who advocate *not* casting the result of
    malloc() do so because of some agenda having to do with C++ is
    unsupported and false.

    Even assuming, for the sake of argument, that you're right and the rest
    of us are wrong, please don't presume to make claims about our motives.

    My reasons for not casting the result of malloc() have nothing to do
    with C++.

    --
    Keith Thompson (The_Other_Keith) <>
    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"
     
    Keith Thompson, Nov 19, 2007
    #19
  20. CJ wrote:
    > 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.


    Can be *implicitly* converted.

    > 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.


    Such implementations are obsolete. Though you can't yet depend on C99
    conformance, you can (except in very rare circumstances) depend on C90
    conformance.

    Before C89/C90, there was no standard. Different implementations did
    very different things. Catering to *all* variations in pre-ANSI
    implementations is extremely difficult and tedious -- which is why the
    ANSI standard was so enthusiastically accepted.

    When was the last time you actually used an implementation that didn't
    have malloc() returning a void* declared in <stdlib.h>?

    --
    Keith Thompson (The_Other_Keith) <>
    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"
     
    Keith Thompson, Nov 19, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ollej Reemt
    Replies:
    7
    Views:
    566
    Jack Klein
    Apr 22, 2005
  2. Stig Brautaset

    `void **' revisited: void *pop(void **root)

    Stig Brautaset, Oct 25, 2003, in forum: C Programming
    Replies:
    15
    Views:
    812
    The Real OS/2 Guy
    Oct 28, 2003
  3. Replies:
    5
    Views:
    850
    S.Tobias
    Jul 22, 2005
  4. Ray Gardener
    Replies:
    3
    Views:
    766
    peter koch
    Apr 19, 2006
  5. Replies:
    1
    Views:
    418
    Victor Bazarov
    May 23, 2007
Loading...

Share This Page