why use typecast on NULL?

Discussion in 'C Programming' started by Xiaofeng Ye, Dec 14, 2004.

  1. Xiaofeng Ye

    Xiaofeng Ye Guest

    Sombody writes:
    HASH_TABLE *hashed_filenames = (HASH_TABLE *)NULL;

    why not:
    HASH_TABLE *hashed_filenames = NULL;

    thanks!
     
    Xiaofeng Ye, Dec 14, 2004
    #1
    1. Advertising

  2. Xiaofeng Ye

    Mike Wahler Guest

    "Xiaofeng Ye" <> wrote in message
    news:cpli09$16n8$99.com...
    > Sombody writes:
    > HASH_TABLE *hashed_filenames = (HASH_TABLE *)NULL;
    >
    > why not:
    > HASH_TABLE *hashed_filenames = NULL;


    Either way is valid. The former might be considered by some to be more
    descriptive. It's a 'style' issue.

    -Mike
     
    Mike Wahler, Dec 14, 2004
    #2
    1. Advertising

  3. Xiaofeng Ye wrote:
    > Sombody writes:
    > HASH_TABLE *hashed_filenames = (HASH_TABLE *)NULL;
    >
    > why not:
    > HASH_TABLE *hashed_filenames = NULL;
    > ...


    There's no formal reason. Might be some weird coding standard or
    personal preference.

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Dec 14, 2004
    #3
  4. Xiaofeng Ye <> writes:
    > Sombody writes:
    > HASH_TABLE *hashed_filenames = (HASH_TABLE *)NULL;
    >
    > why not:
    > HASH_TABLE *hashed_filenames = NULL;


    No good reason at all. The latter is simpler and clearer.
    Casts should be used only when they're actually necessary.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Dec 14, 2004
    #4
  5. Xiaofeng Ye

    Dan Pop Guest

    In <cpli09$16n8$99.com> Xiaofeng Ye <> writes:

    >Sombody writes:
    >HASH_TABLE *hashed_filenames = (HASH_TABLE *)NULL;
    >
    >why not:
    >HASH_TABLE *hashed_filenames = NULL;


    There is exactly one instance when NULL needs to be cast: when passed as
    argument to a variadic function (or a non-prototyped function, but there
    is no good reason for not prototyping your functions).

    Otherwise, the compiler has enough context information to figure out to
    what type the null pointer constant needs to be converted and the
    conversion is automatic.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Currently looking for a job in the European Union
     
    Dan Pop, Dec 14, 2004
    #5
  6. Dan Pop <> wrote:
    > In <cpli09$16n8$99.com> Xiaofeng Ye <> writes:


    > >Sombody writes:
    > >HASH_TABLE *hashed_filenames = (HASH_TABLE *)NULL;
    > >
    > >why not:
    > >HASH_TABLE *hashed_filenames = NULL;


    > There is exactly one instance when NULL needs to be cast: when passed as
    > argument to a variadic function (or a non-prototyped function, but there
    > is no good reason for not prototyping your functions).


    On OpenBSD NULL is defined as simply `0'. And int's are 32-bits while
    pointers 64-bits. The second scenario goes something like:

    #include <stdlib.h>
    #include <errno.h>

    struct something;

    struct something *func(void) {
    return errno = EINVAL, NULL; /* Should be (struct something *)0
    * or (void *)0 or (void *)NULL
    * or (struct something *)NULL
    */
    }

    int main(void) {
    func();

    return 0;
    }
     
    William Ahern, Dec 14, 2004
    #6
  7. On Tue, 14 Dec 2004, William Ahern wrote:
    >
    > Dan Pop <> wrote:
    >> There is exactly one instance when NULL needs to be cast: when passed as
    >> argument to a variadic function (or a non-prototyped function, but there
    >> is no good reason for not prototyping your functions).

    >
    > On OpenBSD NULL is defined as simply `0'. And int's are 32-bits while
    > pointers 64-bits. The second scenario goes something like:
    >
    > #include <stdlib.h>
    > #include <errno.h>
    >
    > struct something;
    >
    > struct something *func(void) {
    > return errno = EINVAL, NULL; /* Should be (struct something *)0
    > * or (void *)0 or (void *)NULL
    > * or (struct something *)NULL
    > */


    Is this right? I was all set to pounce on it as incorrect, but
    then I hesitated. Is there something magic about the comma operator
    in this example? Obviously

    return NULL;

    is fine --- that's a pointer context, and 'NULL' is converted correctly.
    Is William's example actually valid, and if so, why?

    (BTW, I would say that's not really a place for casting NULL even if
    William is right. I'd rewrite it as
    errno = EINVAL; return NULL;
    No casts necessary.)

    -Arthur
     
    Arthur J. O'Dwyer, Dec 14, 2004
    #7
  8. Arthur J. O'Dwyer <> wrote:
    > On Tue, 14 Dec 2004, William Ahern wrote:
    > >
    > > Dan Pop <> wrote:
    > >> There is exactly one instance when NULL needs to be cast: when passed as
    > >> argument to a variadic function (or a non-prototyped function, but there
    > >> is no good reason for not prototyping your functions).

    > >
    > > On OpenBSD NULL is defined as simply `0'. And int's are 32-bits while
    > > pointers 64-bits. The second scenario goes something like:
    > >
    > > #include <stdlib.h>
    > > #include <errno.h>
    > >
    > > struct something;
    > >
    > > struct something *func(void) {
    > > return errno = EINVAL, NULL; /* Should be (struct something *)0
    > > * or (void *)0 or (void *)NULL
    > > * or (struct something *)NULL
    > > */

    >
    > Is this right? I was all set to pounce on it as incorrect, but
    > then I hesitated. Is there something magic about the comma operator
    > in this example? Obviously
    >
    > return NULL;
    >
    > is fine --- that's a pointer context, and 'NULL' is converted correctly.
    > Is William's example actually valid, and if so, why?


    See this thread

    http://groups-beta.google.com/group...read/thread/6d46b6a1bb410cb0/bb12342d62b175e8

    Specifically, Kevin Easton's remark

    result of the comma operator is the type and value of the
    _right hand_ expression, not the left.

    > (BTW, I would say that's not really a place for casting NULL even if
    > William is right. I'd rewrite it as
    > errno = EINVAL; return NULL;
    > No casts necessary.)


    I use it often to keep my error detection terse. I don't tend to skimp on
    error checking and using braces everytime tends to distract from the common
    path.

    if (a == NULL || b == NULL)
    return errno = EINVAL, -1;

    And more importantly, that speaks to me more than using two statements. In a
    sense what I am actually returning is a new errno *and* -1.

    - Bill
     
    William Ahern, Dec 14, 2004
    #8
  9. Xiaofeng Ye

    Chris Torek Guest

    >On Tue, 14 Dec 2004, William Ahern wrote:
    >> struct something *func(void) {
    >> return errno = EINVAL, NULL; /* Should be (struct something *)0
    >> * or (void *)0 or (void *)NULL
    >> * or (struct something *)NULL
    >> */


    In article <>,
    Arthur J. O'Dwyer <> wrote:
    > Is this right? I was all set to pounce on it as incorrect, but
    >then I hesitated. Is there something magic about the comma operator
    >in this example? Obviously
    >
    > return NULL;
    >
    >is fine --- that's a pointer context, and 'NULL' is converted correctly.
    >Is William's example actually valid, and if so, why?


    I believe so, yes. The problem is that comma-expressions are not
    constant-expressions, according to the Standard. If NULL is defined
    as 0 -- which is of course legitimate -- then this line expands to
    something like:

    return errno = 42, 0;

    A comma-expression is not a constant, not even when both its operands
    are constants, as in (3,4). (Our expression in question has a
    side-effect on the left-hand side, so it would be still be "not a
    constant" according to such a rule, not that either C standard has
    such a rule.) Since a null pointer constant is obtained only with
    an integral *constant* expression with value 0 (possibly with an
    attached cast to (void *)), and this zero is not constant, this
    must not be a null pointer constant.

    > (BTW, I would say that's not really a place for casting NULL even if
    >William is right. I'd rewrite it as
    > errno = EINVAL; return NULL;
    >No casts necessary.)


    Yes, this is much cleaner for a future maintainer.
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Dec 14, 2004
    #9
  10. William Ahern wrote:
    > ...
    > On OpenBSD NULL is defined as simply `0'. And int's are 32-bits while
    > pointers 64-bits. The second scenario goes something like:
    >
    > #include <stdlib.h>
    > #include <errno.h>
    >
    > struct something;
    >
    > struct something *func(void) {
    > return errno = EINVAL, NULL; /* Should be (struct something *)0
    > * or (void *)0 or (void *)NULL
    > * or (struct something *)NULL
    > */
    > }
    > ...


    An expression that contains comma operator or assignment operator is not
    a NPC (null pointer constant). Forcing such an expression to pointer
    type is not guaranteed to result in NPV (null pointer value). Without a
    cast this code is broken. The original one isn't.

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Dec 14, 2004
    #10
  11. On Tue, 14 Dec 2004, William Ahern wrote:
    >
    > Arthur J. O'Dwyer <> wrote:
    >> On Tue, 14 Dec 2004, William Ahern wrote:
    >>> Dan Pop <> wrote:
    >>>> There is exactly one instance when NULL needs to be cast: when passed as
    >>>> argument to a variadic function (or a non-prototyped function, but there
    >>>> is no good reason for not prototyping your functions).

    >>
    >>> struct something *func(void) {
    >>> return errno = EINVAL, NULL;

    >>
    >> Is this right? I was all set to pounce on it as incorrect, but
    >> then I hesitated. Is there something magic about the comma operator
    >> in this example?


    Ah yes, the comma operator cannot be used in constant expressions. So
    we end up trying to convert the (non-constant-expression) integer 0 to
    a pointer type, and failing. You're right. Thanks.

    Re: readability, I still maintain that you can have your cake and eat
    it too. If I really ended up writing this sort of thing a lot (which I
    don't, since I don't use 'errno' to report errors in my own code), I'd
    probably use a macro like

    #define RETURN_ERRNO(x,y) do { errno=(x); return y; } while (0)

    (Pedantic treat: I'm not happy with the macro's name, since it takes a
    return value and an errno value, but not in that order. But if I called
    it 'ERRNO_RETURN', it would invade the implementation's namespace. And
    if I simply reversed the parameters, it would use them in the opposite
    order from how they were passed, which seems unintuitive. Quite the
    dilemma! :)

    -Arthur
     
    Arthur J. O'Dwyer, Dec 15, 2004
    #11
    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. Replies:
    5
    Views:
    26,712
    Mike Schilling
    Mar 29, 2006
  2. Carl
    Replies:
    21
    Views:
    997
    Patricia Shanahan
    Aug 24, 2006
  3. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    913
    Mark Rae
    Dec 21, 2006
  4. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,008
    Smokey Grindel
    Dec 2, 2006
  5. su
    Replies:
    3
    Views:
    776
    CBFalconer
    Jan 23, 2009
Loading...

Share This Page