Re: is there anything unstandard in the c part here

Discussion in 'C Programming' started by John Gordon, Jul 26, 2011.

  1. John Gordon

    John Gordon Guest

    In <> Uno <> writes:

    > char * testc() {


    If testc() doesn't take any arguments, then spell it out explicitly:

    char *testc(void)

    > char * pa;
    > pa = (char *)malloc (50);


    Don't cast the return value of malloc. There's no need, and it can hide
    errors later on if you change the type of pa but forget to change the
    cast.

    > strcpy((char *)pa, "this sentence is less than fifty bytes.");


    Why are you casting pa to a char pointer when it already is one?

    --
    John Gordon A is for Amy, who fell down the stairs
    B is for Basil, assaulted by bears
    -- Edward Gorey, "The Gashlycrumb Tinies"
    John Gordon, Jul 26, 2011
    #1
    1. Advertising

  2. John Gordon

    gwowen Guest

    On Jul 26, 12:53 am, John Gordon <> wrote:
    >   char *testc(void)
    >
    > >      char * pa;
    > >      pa = (char *)malloc (50);

    >
    > Don't cast the return value of malloc.  There's no need, and it can hide
    > errors later on if you change the type of pa but forget to change the
    > cast.


    Please don't give (distinctly debatable) style tips as if they were
    hard and fast rules. Not casting malloc has both benefits and
    drawbacks w.r.t. hiding bugs, and to suggest otherwise is to
    demonstrate incomplete understanding.
    gwowen, Jul 26, 2011
    #2
    1. Advertising

  3. John Gordon

    tom st denis Guest

    On Jul 26, 4:50 am, gwowen <> wrote:
    > On Jul 26, 12:53 am, John Gordon <> wrote:
    >
    > >   char *testc(void)

    >
    > > >      char * pa;
    > > >      pa = (char *)malloc (50);

    >
    > > Don't cast the return value of malloc.  There's no need, and it can hide
    > > errors later on if you change the type of pa but forget to change the
    > > cast.

    >
    > Please don't give (distinctly debatable) style tips as if they were
    > hard and fast rules.  Not casting malloc has both benefits and
    > drawbacks w.r.t. hiding bugs, and to suggest otherwise is to
    > demonstrate incomplete understanding.


    In C you do not need to cast void* to any other pointer type.
    Specifically casting it to silence warnings shows you're doing
    something wrong. By default the compiler will think that malloc
    returns "int" which in many cases is not the same size [or more
    importantly castable] as a pointer.

    I'd also point out this is something trolls question repeatedly to get
    a rise out of the regulars [who aren't trolls, I'd argue the trolls
    are also part of the set of regulars, just not the helpful subset].

    Tom
    tom st denis, Jul 26, 2011
    #3
  4. John Gordon

    James Kuyper Guest

    On 07/26/2011 04:50 AM, gwowen wrote:
    > On Jul 26, 12:53�am, John Gordon <> wrote:
    >> � char *testc(void)
    >>
    >>> � � �char * pa;
    >>> � � �pa = (char *)malloc (50);

    >>
    >> Don't cast the return value of malloc. �There's no need, and it can hide
    >> errors later on if you change the type of pa but forget to change the
    >> cast.

    >
    > Please don't give (distinctly debatable) style tips as if they were
    > hard and fast rules. Not casting malloc has both benefits and
    > drawbacks w.r.t. hiding bugs, and to suggest otherwise is to
    > demonstrate incomplete understanding.


    What are the drawbacks? I'm not familiar with any.
    --
    James Kuyper
    James Kuyper, Jul 26, 2011
    #4
  5. John Gordon

    John Gordon Guest

    In <> gwowen <> writes:

    > > Don't cast the return value of malloc. There's no need, and it can
    > > hide errors later on if you change the type of pa but forget to change
    > > the cast.


    > Please don't give (distinctly debatable) style tips as if they were
    > hard and fast rules. Not casting malloc has both benefits and
    > drawbacks w.r.t. hiding bugs, and to suggest otherwise is to
    > demonstrate incomplete understanding.


    I am unaware that casting malloc has any benefits at all. Please
    elaborate.

    --
    John Gordon A is for Amy, who fell down the stairs
    B is for Basil, assaulted by bears
    -- Edward Gorey, "The Gashlycrumb Tinies"
    John Gordon, Jul 26, 2011
    #5
  6. John Gordon

    Chad Guest

    On Jul 26, 8:01 am, Kenneth Brody <> wrote:
    > On 7/26/2011 4:50 AM, gwowen wrote:
    >
    > > On Jul 26, 12:53 am, John Gordon<>  wrote:
    > >>    char *testc(void)

    >
    > >>>       char * pa;
    > >>>       pa = (char *)malloc (50);

    >
    > >> Don't cast the return value of malloc.  There's no need, and it can hide
    > >> errors later on if you change the type of pa but forget to change the
    > >> cast.

    >
    > > Please don't give (distinctly debatable) style tips as if they were
    > > hard and fast rules.  Not casting malloc has both benefits and
    > > drawbacks w.r.t. hiding bugs, and to suggest otherwise is to
    > > demonstrate incomplete understanding.

    >
    > Please explain when, in C, there is a "benefit" to casting the return from
    > malloc().
    >
    > Unless you are using an ancient C compiler which predates "void *", thereis
    > no good reason I can think of for casting the return from malloc().  And,
    > even on those ancient systems, the return was defined as "char *", making
    > the cast in the instant case redundant.
    >


    Let's say I'm working on a programming project that uses multiple
    languages. And now let's say that the only (apparent) way I can get C
    to cooperate with the other programming languages is to cast the
    return value from malloc(). How would you get around avoiding casting
    the return from malloc()?

    Chad
    Chad, Jul 26, 2011
    #6
  7. John Gordon

    John Gordon Guest

    In <> Chad <> writes:

    > Let's say I'm working on a programming project that uses multiple
    > languages. And now let's say that the only (apparent) way I can get C
    > to cooperate with the other programming languages is to cast the
    > return value from malloc(). How would you get around avoiding casting
    > the return from malloc()?


    If you're calling malloc() from within a module written in another
    language, then you should use whatever mechanism that language provides
    for coercing the return value of malloc() into a compatible representation.
    But this isn't C casting, so this example is irrelevant.

    If you're calling malloc() from within C code, the presence elsewhere in
    your program of modules written in other languages is irrelevant.

    In short, I don't see how other languages are relevant to this discussion.

    --
    John Gordon A is for Amy, who fell down the stairs
    B is for Basil, assaulted by bears
    -- Edward Gorey, "The Gashlycrumb Tinies"
    John Gordon, Jul 26, 2011
    #7
  8. John Gordon

    Angel Guest

    On 2011-07-26, Chad <> wrote:
    > On Jul 26, 8:01?am, Kenneth Brody <> wrote:
    >>
    >> Please explain when, in C, there is a "benefit" to casting the return from
    >> malloc().
    >>
    >> Unless you are using an ancient C compiler which predates "void *", there is
    >> no good reason I can think of for casting the return from malloc(). ?And,
    >> even on those ancient systems, the return was defined as "char *", making
    >> the cast in the instant case redundant.
    >>

    >
    > Let's say I'm working on a programming project that uses multiple
    > languages. And now let's say that the only (apparent) way I can get C
    > to cooperate with the other programming languages is to cast the
    > return value from malloc(). How would you get around avoiding casting
    > the return from malloc()?


    I would say that you're either doing something very wrong or your
    implementation is broken.


    --
    "C provides a programmer with more than enough rope to hang himself.
    C++ provides a firing squad, blindfold and last cigarette."
    - seen in comp.lang.c
    Angel, Jul 26, 2011
    #8
  9. John Gordon

    tom st denis Guest

    On Jul 26, 11:08 am, Kenneth Brody <> wrote:
    > On 7/26/2011 9:17 AM, tom st denis wrote:
    > [...]> In C you do not need to cast void* to any other pointer type.
    > > Specifically casting it to silence warnings shows you're doing
    > > something wrong.  By default the compiler will think that malloc
    > > returns "int" which in many cases is not the same size [or more
    > > importantly castable] as a pointer.

    >
    > [...]
    >
    > More importantly still are those platforms with separate "data" and
    > "address" registers, on which a pointer value is returned on a totally
    > distinct register than an integer value.  On such platforms, it's not just
    > that the value it sees can't be properly cast to a pointer, but it's looking
    > in the wrong place to begin with.


    Also a good point ya.

    Generally speaking I don't get why they insist on bringing it up over
    and over. Header files took me all of no time to learn when I was
    teaching myself the very basics of C when I was 10. Admittedly I
    wasn't a developer then, but it wasn't exactly rocket surgery to
    realize "oh wait, I need to include the definition of the function
    with a header so the compiler knows how the function call works..."

    Usually if I don't have it memorized I just read the man page. Takes
    me three seconds to look up a C function and I'm on my way.

    Oddly enough the time these people save by writing quick and dirty
    code they usually lose in multiple-fold by having to debug it later...

    Tom
    tom st denis, Jul 26, 2011
    #9
  10. John Gordon

    Seebs Guest

    On 2011-07-26, gwowen <> wrote:
    > Please don't give (distinctly debatable) style tips as if they were
    > hard and fast rules. Not casting malloc has both benefits and
    > drawbacks w.r.t. hiding bugs, and to suggest otherwise is to
    > demonstrate incomplete understanding.


    Could you give an example of a case, in C, where not casting malloc hides
    a bug that would have been caught had it been cast?

    -s
    --
    Copyright 2011, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    I am not speaking for my employer, although they do rent some of my opinions.
    Seebs, Jul 26, 2011
    #10
  11. John Gordon

    Seebs Guest

    On 2011-07-26, Chad <> wrote:
    > Let's say I'm working on a programming project that uses multiple
    > languages.


    Hmm. Maybe?

    > And now let's say that the only (apparent) way I can get C
    > to cooperate with the other programming languages is to cast the
    > return value from malloc().


    This is "begging the question"; you're simply assuming that the cast
    is necessary, without showing *how* it could be necessary.

    > How would you get around avoiding casting
    > the return from malloc()?


    By not assuming something which isn't true.

    Compile C code in C. Don't compile C code in other languages. If you need
    to mix C and other languages, do it by separating C and other languages into
    separate hunks of code. Compile C with the C compiler, which does not need
    casts for malloc. If you need to call C from another language, do so by
    using whatever tools that language has for calling C.

    -s
    --
    Copyright 2011, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    I am not speaking for my employer, although they do rent some of my opinions.
    Seebs, Jul 26, 2011
    #11
  12. John Gordon

    Paul N Guest

    On Jul 26, 3:58 pm, John Gordon <> wrote:

    > I am unaware that casting malloc has any benefits at all.  Please
    > elaborate.


    (and James Kuyper and Kenneth Brody asked similar things)

    1) As Kenneth Brody has pointed out, it means your code will work with
    an ancient compiler in which malloc returns a char *.

    2) It means that the code doesn't need to be re-written should you
    wish to treat it as C++ code.

    3) Some programmers just feel it is "wrong" to assign a value of one
    type to a variable of another, and this will make them feel happier
    about the code. I presume there are no program checking tools which
    feel likewise, though this would help if there were.

    So that's three arguable benefits, though there is obviously a strong
    argument that they are outweighed by the benefits of not casting.
    Paul N, Jul 26, 2011
    #12
  13. John Gordon

    Guest

    Bill Waddington <> wrote:
    >
    > Oh my. Someone who knows what "begging the question" actaully means.


    There are still lots of us around, although we are greatly outnumbered.
    --
    Larry Jones

    Hey Doc, for 10 bucks I'll make sure you see those kids in the
    waiting room again real soon! -- Calvin
    , Jul 26, 2011
    #13
  14. On Jul 26, 9:50 am, gwowen <> wrote:
    > On Jul 26, 12:53 am, John Gordon <> wrote:
    >
    > >   char *testc(void)

    >
    > > >      char * pa;
    > > >      pa = (char *)malloc (50);

    >
    > > Don't cast the return value of malloc.  There's no need, and it can hide
    > > errors later on if you change the type of pa but forget to change the
    > > cast.

    >
    > Please don't give (distinctly debatable) style tips as if they were
    > hard and fast rules.  Not casting malloc has both benefits and
    > drawbacks w.r.t. hiding bugs, and to suggest otherwise is to
    > demonstrate incomplete understanding.


    but on balance omitting the cast is the best option. Putting an
    unnecesary cast in can hide bug. I don't see how leaving out the cast
    can hide bugs.

    The only good reason for casting malloc that I can see is that you're
    compiling K&R C or using a C++ compiler. The Dinkum people who
    maintain both C and C++ libraries reckon they have justification. But
    hardly anyone else has.
    Nick Keighley, Jul 27, 2011
    #14
  15. On Jul 26, 6:51 pm, tom st denis <> wrote:
    > On Jul 26, 11:08 am, Kenneth Brody <> wrote:
    >
    > > On 7/26/2011 9:17 AM, tom st denis wrote:
    > > [...]> In C you do not need to cast void* to any other pointer type.
    > > > Specifically casting it to silence warnings shows you're doing
    > > > something wrong.  By default the compiler will think that malloc
    > > > returns "int" which in many cases is not the same size [or more
    > > > importantly castable] as a pointer.

    >
    > > [...]

    >
    > > More importantly still are those platforms with separate "data" and
    > > "address" registers, on which a pointer value is returned on a totally
    > > distinct register than an integer value.  On such platforms, it's notjust
    > > that the value it sees can't be properly cast to a pointer, but it's looking
    > > in the wrong place to begin with.

    >
    > Also a good point ya.
    >
    > Generally speaking I don't get why they insist on bringing it up over
    > and over.  Header files took me all of no time to learn when I was
    > teaching myself the very basics of C when I was 10.  Admittedly I
    > wasn't a developer then, but it wasn't exactly rocket surgery to
    > realize "oh wait, I need to include the definition of the function
    > with a header so the compiler knows how the function call works..."
    >
    > Usually if I don't have it memorized I just read the man page.  Takes
    > me three seconds to look up a C function and I'm on my way.
    >
    > Oddly enough the time these people save by writing quick and dirty
    > code they usually lose in multiple-fold by having to debug it later...


    I always thought it should have been an error diagnosed by the
    compiler- to not have a prototype in scope.
    Nick Keighley, Jul 27, 2011
    #15
  16. On Jul 26, 10:56 pm, Paul N <> wrote:
    > On Jul 26, 3:58 pm, John Gordon <> wrote:



    > > I am unaware that casting malloc has any benefits at all.  Please
    > > elaborate.

    >
    > (and James Kuyper and Kenneth Brody asked similar things)
    >
    > 1) As Kenneth Brody has pointed out, it means your code will work with
    > an ancient compiler in which malloc returns a char *.
    >
    > 2) It means that the code doesn't need to be re-written should you
    > wish to treat it as C++ code.


    if you're in one of those environemtns then so be it.

    > 3) Some programmers just feel it is "wrong" to assign a value of one
    > type to a variable of another, and this will make them feel happier
    > about the code.


    I'd say the programmer needed debugging...


    > I presume there are no program checking tools which
    > feel likewise,


    if there are they should be cast into the Outer Darkness. Sounds like
    a very broken lint.


    > though this would help if there were.


    how does a tool that generates spurious "errors" help anyone?


    > So that's three arguable benefits,


    two weird environments and a programwer that needs re-education

    > though there is obviously a strong
    > argument that they are outweighed by the benefits of not casting.


    yay!
    Nick Keighley, Jul 27, 2011
    #16
  17. John Gordon

    James Kuyper Guest

    On 07/27/2011 02:24 AM, Gareth Owen wrote:
    > James Kuyper <> writes:
    >
    >> What are the drawbacks? I'm not familiar with any.

    >
    > Lets look at the code (roughly) as given
    >
    > char *pa;
    > /* yadda yadda yadda */
    > .
    > .
    > .
    > pa = (char*) malloc(50);
    > .
    > .
    > .
    > /* code that presumably assumes 50 elements in pa[] */
    >
    >
    > Now the advice given was "if you change the type of *pa, the cast is
    > wrong". So lets do that...
    >
    > With the cast
    > -----------------------------------------------------------------------------
    > int *pa;
    > /* yadda yadda yadda */
    > .
    > .
    > .
    > pa = (char*) malloc(50);
    > .
    > .
    > .
    > /* code that presumably assumes 50 elements in pa[] */
    > result: compiler error.
    > -----------------------------------------------------------------------------
    >
    >
    > Take the cast away
    > -----------------------------------------------------------------------------
    > int *pa;
    > /* yadda yadda yadda */
    > .
    > .
    > .
    > pa = malloc(50);
    > .
    > .
    > .
    > /* code that presumably assumes 50 elements in pa[] */
    > result: undefined behaviour unless sizeof(int) == 1
    >
    > The *failure* to cast malloc() has hidden a bug in *exactly* the case for
    > which casting malloc() was held up as being wrong.


    Well, no. If the missing cast were the the problem, then inserting an
    (int*) would be the solution - in fact, the real problem would persist
    even if an (int*) were inserted.

    The change from (char*) to (int*) is not the solution, it's the problem.
    If you have a policy of casting the value returned by malloc(), then you
    have to modify the cast any time you change the type. It's a minor waste
    of time, which doesn't come up very often. It would be easily
    justifiable if it provided any corresponding benefit - but it provides
    none. What needs to be matched up isn't the type, its the size, and you
    can't do anything about that with a cast.

    > Personally, when I accidentally write buggy code, I want a compiler
    > error rather undefined behaviour. YMMV.


    Nothing you can do in C will cause the real problem, the incorrect size
    passed to malloc(), to be flagged as a compiler error. However, what you
    can do is ensure that the size passed to malloc() is correct, regardless
    of the type:

    > Yes, I know all about the pa = malloc(50 * sizeof(*pa)) idiom, thanks,


    So, in other words, you do know that the problem is not the "missing"
    cast, but the argument passed to malloc().

    > and I know that there *are* drawbacks to casting malloc. But my
    > underlying point is correct - casting malloc() is a *style* issue, and
    > only idiots argue that their style is correct and anything else is
    > wrong.


    There's style, and then there's functionality. Indentation is a pure
    style issue; any consistently applied indentation style is workable, and
    arguing over them is pointless. Unnecessarily casting the value returned
    by malloc() is just a waste of time. However, passing the correct size
    to malloc() is a functionality issue, not a size issue.
    --
    James Kuyper
    James Kuyper, Jul 27, 2011
    #17
  18. John Gordon

    James Kuyper Guest

    On 07/26/2011 05:56 PM, Paul N wrote:
    > On Jul 26, 3:58�pm, John Gordon <> wrote:
    >
    >> I am unaware that casting malloc has any benefits at all. �Please
    >> elaborate.

    >
    > (and James Kuyper and Kenneth Brody asked similar things)
    >
    > 1) As Kenneth Brody has pointed out, it means your code will work with
    > an ancient compiler in which malloc returns a char *.


    Yes, those compilers are ancient. The standard which changed that was
    approved before the latest crop of computer programmers was even born. I
    stopped worrying about compatibility with pre-standard compilers nearly
    two decades ago.

    > 2) It means that the code doesn't need to be re-written should you
    > wish to treat it as C++ code.


    True, but that's not a C issue.

    > 3) Some programmers just feel it is "wrong" to assign a value of one
    > type to a variable of another, and this will make them feel happier
    > about the code. I presume there are no program checking tools which
    > feel likewise, though this would help if there were.


    If they're right, arguments supporting the idea that they're right would
    be relevant; the fact that they feel that way is irrelevant. If they're
    wrong, as I believe them to be, the right solution is the re-education
    of or the choice of an alternative career by those programmers, not
    unnecessary casts.

    The whole point of using void* rather than char* (when it's appropriate
    to do so) is the implicit conversions to and from other pointer types.
    Making those conversions implicit simplifies code like this by not
    mandating casts that don't buy any real advantage. Anyone who thinks
    that's a bad idea should probably consider writing a bunch of wrapper
    functions for those standard library functions which use void*. Then any
    use of my_malloc() without a cast, for any purpose other than filling in
    a char*, would guarantee the pointless diagnostic they crave.
    --
    James Kuyper
    James Kuyper, Jul 27, 2011
    #18
  19. On Jul 27, 12:28 pm, James Kuyper <> wrote:
    > On 07/26/2011 05:56 PM, Paul N wrote:
    >
    > > On Jul 26, 3:58 pm, John Gordon <> wrote:

    >
    > >> I am unaware that casting malloc has any benefits at all. Please
    > >> elaborate.

    >
    > > (and James Kuyper and Kenneth Brody asked similar things)

    >
    > > 1) As Kenneth Brody has pointed out, it means your code will work with
    > > an ancient compiler in which malloc returns a char *.

    >
    > Yes, those compilers are ancient. The standard which changed that was
    > approved before the latest crop of computer programmers was even born. I
    > stopped worrying about compatibility with pre-standard compilers nearly
    > two decades ago.


    I made a change to a K&R program about 12 months ago. My first time!

    <snip>
    Nick Keighley, Jul 27, 2011
    #19
  20. John Gordon

    Noob Guest

    Gareth Owen wrote:

    > Lets look at the code (roughly) as given
    >
    > char *pa;
    > pa = (char*) malloc(50);
    > /* code that presumably assumes 50 elements in pa[] */


    "elements" is unnecessarily vague;
    pa can (only) store 50 CHARACTERS,
    (whether the cast is there or not.)

    > Now the advice given was "if you change the type of *pa,
    > the cast is wrong". So lets do that...
    >
    > With the cast
    >
    > int *pa;
    > pa = (char*) malloc(50);
    > /* code that presumably assumes 50 elements in pa[] */


    The problem is to assume that pa can store anything else
    but 50 CHARACTERS, since that is what was requested... o_O

    So you go back to the assignment, and write what?

    pa = (int *) malloc(50*4); // not portable

    pa = (int *) malloc(50*sizeof(int));

    Why are you trying SO HARD to avoid the IDIOMATIC

    pa = malloc(50 * sizeof *pa);

    which doesn't require dicking around should you ever
    want to modify pa's type?
    Noob, Jul 27, 2011
    #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. Mano kumar
    Replies:
    2
    Views:
    355
    Kevin Spencer
    Oct 17, 2003
  2. Replies:
    10
    Views:
    1,329
    Malte
    Jun 30, 2005
  3. Replies:
    5
    Views:
    502
  4. Barry Schwarz

    Re: is there anything unstandard in the c part here

    Barry Schwarz, Jul 26, 2011, in forum: C Programming
    Replies:
    11
    Views:
    398
    Nobody
    Jul 27, 2011
  5. Nick Keighley

    Re: is there anything unstandard in the c part here

    Nick Keighley, Jul 26, 2011, in forum: C Programming
    Replies:
    16
    Views:
    554
    Ike Naar
    Aug 1, 2011
Loading...

Share This Page