About FAQ 5.4

Discussion in 'C Programming' started by I wish, Oct 14, 2003.

  1. I wish

    I wish Guest

    http://www.eskimo.com/~scs/C-faq/q5.4.html

    It says "In particular, a cast may still be necessary before NULL

    (as before 0) in a function call argument."

    Does that mean if I want to pass a NULL to a function,

    I should write like this

    foo( (char *)NULL ); /* Assume foo receive a pointer to char */
    | Modify | Tue, 14 Oct 2003 22:10:40 +0800 (CST)
    I wish, Oct 14, 2003
    #1
    1. Advertising

  2. I wish

    Eric Sosman Guest

    I wish wrote:
    >
    > http://www.eskimo.com/~scs/C-faq/q5.4.html
    >
    > It says "In particular, a cast may still be necessary before NULL
    >
    > (as before 0) in a function call argument."
    >
    > Does that mean if I want to pass a NULL to a function,
    >
    > I should write like this
    >
    > foo( (char *)NULL ); /* Assume foo receive a pointer to char */


    There are essentially two cases: One where the compiler
    already knows what kind of pointer foo() expects, and one
    where it does not know. The latter has two sub-cases:

    1. If a prototype for foo() is in scope at the point of
    the call, the compiler knows that foo() expects to
    receive a `char*' (or a `double*' or `struct x*' or
    whatever). In this case, the compiler arranges to
    have NULL converted to the desired type automatically;
    the cast is unnecessary but harmless.

    2a. If there is no prototype for foo() the compiler does
    not know what kind of argument is expected. In this
    case, the supplied argument is handled according to
    the "default argument promotions," which may or may
    not produce the correct result. For example, if NULL
    is defined as an unadorned `0', the compiler will pass
    the argument as an `int' and not as a `char*'. In
    this instance, the cast is required.

    2b. If a prototype for foo() is in scope but foo() is a
    variadic function and the argument in question is one
    of the `...' optional arguments, once again the compiler
    doesn't know what kind of argument is expected. For the
    fixed arguments before the `...' the situation is as in
    case [1], but the `...' arguments are handled as in [2a]:
    the default argument promotions prevail, and you need
    an explicit cast to override them.

    --
    Eric Sosman, Oct 14, 2003
    #2
    1. Advertising

  3. I wish wrote:
    > It says "In particular, a cast may still be necessary before NULL (as
    > before 0) in a function call argument."
    >
    > Does that mean if I want to pass a NULL to a function, I should write
    > like this
    >
    > foo( (char *)NULL ); /* Assume foo receive a pointer to char */


    This is addressed in question 5.2:

    http://www.eskimo.com/~scs/C-faq/q5.2.html

    The gist of it is you have to use a cast only when a) there is no function
    prototype in scope, or b) the argument is part of a variable-length argument
    list.

    Note that the author (Steve Summit) recommends you cast NULL whenever you
    pass it to a function. He lists a few reasons for saying that. I see his
    point, but I don't think I'd want to adopt that practice for my own code.
    In my opinion, unnecessary casts should be avoided, because they decrease
    the legibility of your code, and could hide programming mistakes.

    --
    Russell Hanneken

    Remove the 'g' from my address to send me mail.
    Russell Hanneken, Oct 14, 2003
    #3
  4. I wish

    Dan Pop Guest

    In <48eEUh$> (I wish) writes:


    > http://www.eskimo.com/~scs/C-faq/q5.4.html
    >
    > It says "In particular, a cast may still be necessary before NULL
    > (as before 0) in a function call argument."
    >
    > Does that mean if I want to pass a NULL to a function,
    > I should write like this
    >
    > foo( (char *)NULL ); /* Assume foo receive a pointer to char */


    ONLY if you don't have a prototype for foo() in scope. Since there is no
    good reason for not properly declaring the functions you're using, the
    only real case when you have to use the cast is when calling variadic
    functions: the compiler has no information about the expected type, so it
    cannot perform the conversion itself.

    Typical example:

    #include <stdio.h>
    ....
    printf("%p\n", (void *)NULL);

    OTOH,

    fflush(NULL);

    is just fine, because the compiler has the prototype of fflush() in scope
    and it can perform the conversion itself.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Oct 14, 2003
    #4
  5. I wish

    Richard Bos Guest

    (I wish) wrote:

    > http://www.eskimo.com/~scs/C-faq/q5.4.html
    >
    > It says "In particular, a cast may still be necessary before NULL
    > (as before 0) in a function call argument."
    >
    > Does that mean if I want to pass a NULL to a function,
    > I should write like this
    >
    > foo( (char *)NULL ); /* Assume foo receive a pointer to char */


    Well, that's debatable.

    If you have a decent prototype[1] in scope, and that prototype tells you
    that the function is not for a variadic function (or that the pointer is
    one of the fixed arguments to a variadic function, not part of the
    variable arguments), then no, you don't need to.
    If you don't have a prototype in scope, you need to, because then the
    compiler can't figure out what type of pointer to convert the null
    pointer constant to - it doesn't know what type is required unless the
    prototype tells it.
    If you the null pointer is one of the variable arguments to a variadic
    function, you also need to cast, because the compiler can't figure out
    what type of pointer is needed - it can in the fixed arguments, of
    course, but there's surprisingly little type information in "...".

    The above is all clear and not really debatable. The debate starts when
    you ask whether, even though you usually don't _need_ to cast a null
    pointer argument, you _should_ do so for stylistic reasons.
    On one side of the argument, if you simply cast all null pointer
    arguments, you don't need to think about it, and you won't forget to
    cast one you must cast.
    On the other side, you need to know about the difference between
    variadic functions and normal ones anyway, and you shouldn't (and in
    C99, can't) call functions without a proper declaration in the first
    place; and any superfluous cast is a hinder to the legibility of your
    code.
    Me, I favour the second side, and only use properly prototyped functions
    whenever I can help it, and cast only null pointer constants passed as
    variadic arguments. But I don't pretend this is an immutable rule -
    unless you're me.

    Richard

    [1] Or complete old-style definition, I presume; but just don't use
    old-style definitions, it's safer. An old-style _declaration_ is not
    good enough, in any case. (And the reason I say "I presume" is that
    I'm not sure; and don't care to find out, because old-style
    definitions are a Bad Thing anyway.)
    Richard Bos, Oct 14, 2003
    #5
  6. (I wish) wrote:

    > http://www.eskimo.com/~scs/C-faq/q5.4.html
    >
    > It says "In particular, a cast may still be necessary before NULL
    >
    > (as before 0) in a function call argument."
    >
    > Does that mean if I want to pass a NULL to a function,
    >
    > I should write like this
    >
    > foo( (char *)NULL ); /* Assume foo receive a pointer to char */


    Only if there is no prototype for foo in scope or foo is a variadic
    function[1], compare FAQ q5.2, as q5.4 suggests: "The table under
    question 5.2 above applies for NULL as well as 0 (an unadorned NULL is
    equivalent to an unadorned 0)."

    [1] Example: you have to explicitly cast a pointer argument to void* for
    evaluation using the "%p" printf format specifier.

    > | Modify | Tue, 14 Oct 2003 22:10:40 +0800 (CST)


    Please drop this escape sequence nonsense, or at least put it after a
    valid signature delimiter. Thank you.

    Regards
    --
    Irrwahn
    ()
    Irrwahn Grausewitz, Oct 14, 2003
    #6
  7. Irrwahn Grausewitz <> scribbled the following:
    > (I wish) wrote:
    >> | Modify | Tue, 14 Oct 2003 22:10:40 +0800 (CST)


    > Please drop this escape sequence nonsense, or at least put it after a
    > valid signature delimiter. Thank you.


    No. Please just drop the escape sequence crap. This is Usenet, not a
    BBS. You can't count on everyone having an MS-DOS relic in their
    newsreader.

    --
    /-- Joona Palaste () ------------- Finland --------\
    \-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
    "It was, er, quite bookish."
    - Horace Boothroyd
    Joona I Palaste, Oct 14, 2003
    #7
  8. I wish <> wrote:
    >
    > http://www.eskimo.com/~scs/C-faq/q5.4.html
    >
    > It says "In particular, a cast may still be necessary before NULL
    >
    > (as before 0) in a function call argument."
    >
    > Does that mean if I want to pass a NULL to a function,
    >
    > I should write like this
    >
    > foo( (char *)NULL ); /* Assume foo receive a pointer to char */


    As others have said, if there is no way for the compiler to know the
    intended type (e.g. no prototype, or varargs), then the default promotions
    are used which can have undesirable consequences. I was bitten by this not
    too long ago, believe it or not (using the comma operator, though). Read
    this thread for a real world scenario:

    http://groups.google.com/groups?th=c18bfdde21e11e83

    The short story is that Linux (or glibc) does:

    #define NULL (void *)0

    whereas *BSD does:

    #define NULL 0
    William Ahern, Oct 14, 2003
    #8
    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. Anand N [MVP]

    C# FAQ 1

    Anand N [MVP], Sep 18, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    637
    Anand N [MVP]
    Sep 19, 2004
  2. =?ISO-8859-15?Q?Juli=E1n?= Albo

    FAQ or not FAQ?

    =?ISO-8859-15?Q?Juli=E1n?= Albo, Jan 8, 2007, in forum: C++
    Replies:
    28
    Views:
    862
    Grizlyk
    Jan 15, 2007
  3. Josef 'Jupp' Schugt
    Replies:
    0
    Views:
    199
    Josef 'Jupp' Schugt
    Sep 22, 2003
  4. FAQ server

    FAQ - How do I direct someone to this FAQ?

    FAQ server, Aug 4, 2006, in forum: Javascript
    Replies:
    1
    Views:
    155
    Dr John Stockton
    Aug 4, 2006
  5. Peter Michaux

    FAQ/FAQ notes site makeover

    Peter Michaux, Nov 22, 2006, in forum: Javascript
    Replies:
    22
    Views:
    354
    Randy Webb
    Nov 27, 2006
Loading...

Share This Page