types, constants and casting

Discussion in 'C Programming' started by Tom Carroll, Sep 2, 2003.

  1. Tom Carroll

    Tom Carroll Guest

    When assigning or testing equality between a type and a constant,
    should the constant be casted to the type?

    I.e.
    should fork() == -1 be written as fork() == (pid_t)-1?
    should uid = 45 be written as uid = (uid_t)45?

    Is the casting necessary? Does it increase portability? Browsing
    some projects, I noticed that -1 is casted but not other values, i.e.
    chown("somefile", 45, (gid_t)-1).

    In short, what is the best practice.

    TIA

    -Tom
     
    Tom Carroll, Sep 2, 2003
    #1
    1. Advertising

  2. Tom Carroll

    Jack Klein Guest

    On 1 Sep 2003 20:41:52 -0700, (Tom
    Carroll) wrote in comp.lang.c:

    > When assigning or testing equality between a type and a constant,
    > should the constant be casted to the type?
    >
    > I.e.
    > should fork() == -1 be written as fork() == (pid_t)-1?
    > should uid = 45 be written as uid = (uid_t)45?
    >
    > Is the casting necessary? Does it increase portability? Browsing
    > some projects, I noticed that -1 is casted but not other values, i.e.
    > chown("somefile", 45, (gid_t)-1).
    >
    > In short, what is the best practice.
    >
    > TIA
    >
    > -Tom


    It does not increase portability at all, at least not for sensibly
    written functions.

    If there is a proper prototype in scope for the function, or at least
    a declaration with the return type specified, and that function
    returns an arithmetic type other than int, the compiler will
    automatically convert -1 to the proper type.

    I seem to recall that there are some (UNIX/POSIX/Linux) functions that
    return a pointer to something if successful, and return (T *)-1,
    instead of a null pointer, if they fail. I hope I am remembering
    incorrectly, because this is not really portable even with a cast.

    In any case, if there is no prototype in scope and the function
    returns something other than int, the result is undefined behavior
    regardless of whether you use the cast.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c /faq
     
    Jack Klein, Sep 2, 2003
    #2
    1. Advertising

  3. Tom Carroll

    j Guest

    "Tom Carroll" <> wrote in message
    news:...
    > When assigning or testing equality between a type and a constant,
    > should the constant be casted to the type?
    >
    > I.e.
    > should fork() == -1 be written as fork() == (pid_t)-1?


    Seems superfluous. As long as fork() returns a value that is considered to
    be of arithmetic type, then the cast is unnecessary.

    > should uid = 45 be written as uid = (uid_t)45?


    As long as ``uid'' is an arithmetic type, then casting is again,
    unnecessary.

    >
    > Is the casting necessary? Does it increase portability?


    No(unless you are forced to use a torturing device such as lint) and no.

    > Browsing
    > some projects, I noticed that -1 is casted but not other values, i.e.
    > chown("somefile", 45, (gid_t)-1).


    As long as a prototype is available for ``chown'', then the cast is
    unnecessary.

    >
    > In short, what is the best practice.
    >


    To understand the constraints of the equality operators and to _never_
    violate those constraints.

    ``Constraints
    2 One of the following shall hold:
    - both operands have arithmetic type;
    - both operands are pointers to qualified or unqualified versions of
    compatible types;
    - 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;or
    - one operand is a pointer and the other is a null pointer constant. ''

    > TIA
    >
    > -Tom
     
    j, Sep 2, 2003
    #3
  4. Tom Carroll

    Kevin Easton Guest

    Jack Klein <> wrote:
    > On 1 Sep 2003 20:41:52 -0700, (Tom
    > Carroll) wrote in comp.lang.c:
    >
    >> When assigning or testing equality between a type and a constant,
    >> should the constant be casted to the type?
    >>
    >> I.e.
    >> should fork() == -1 be written as fork() == (pid_t)-1?
    >> should uid = 45 be written as uid = (uid_t)45?
    >>
    >> Is the casting necessary? Does it increase portability? Browsing
    >> some projects, I noticed that -1 is casted but not other values, i.e.
    >> chown("somefile", 45, (gid_t)-1).
    >>
    >> In short, what is the best practice.
    >>
    >> TIA
    >>
    >> -Tom

    >
    > It does not increase portability at all, at least not for sensibly
    > written functions.
    >
    > If there is a proper prototype in scope for the function, or at least
    > a declaration with the return type specified, and that function
    > returns an arithmetic type other than int, the compiler will
    > automatically convert -1 to the proper type.


    That's not true. Consider:

    #include <stdio.h>

    typedef unsigned short foo_t;

    foo_t do_thing()
    {
    return -1;
    }

    int main()
    {
    if (do_thing() == -1)
    puts("y");
    else
    puts("n");

    return 0;
    }

    Which on many typical implementations will require a (foo_t) cast on the
    -1 for the comparison to ever succeed.

    On the other hand, the cast in the function call:

    >> chown("somefile", 45, (gid_t)-1).


    is never required, so long as the function has a prototyped declaration
    in scope.

    - Kevin.
     
    Kevin Easton, Sep 2, 2003
    #4
  5. Tom Carroll

    Jack Klein Guest

    On Tue, 02 Sep 2003 06:19:51 GMT, Kevin Easton
    <> wrote in comp.lang.c:

    > Jack Klein <> wrote:
    > > On 1 Sep 2003 20:41:52 -0700, (Tom
    > > Carroll) wrote in comp.lang.c:
    > >
    > >> When assigning or testing equality between a type and a constant,
    > >> should the constant be casted to the type?
    > >>
    > >> I.e.
    > >> should fork() == -1 be written as fork() == (pid_t)-1?
    > >> should uid = 45 be written as uid = (uid_t)45?
    > >>
    > >> Is the casting necessary? Does it increase portability? Browsing
    > >> some projects, I noticed that -1 is casted but not other values, i.e.
    > >> chown("somefile", 45, (gid_t)-1).
    > >>
    > >> In short, what is the best practice.
    > >>
    > >> TIA
    > >>
    > >> -Tom

    > >
    > > It does not increase portability at all, at least not for sensibly
    > > written functions.
    > >
    > > If there is a proper prototype in scope for the function, or at least
    > > a declaration with the return type specified, and that function
    > > returns an arithmetic type other than int, the compiler will
    > > automatically convert -1 to the proper type.

    >
    > That's not true. Consider:
    >
    > #include <stdio.h>
    >
    > typedef unsigned short foo_t;
    >
    > foo_t do_thing()
    > {
    > return -1;
    > }


    Sad to say, you are absolutely right and I was wrong.

    I would like to be able to say nobody in their right mind would write
    code like this using an unsigned type of lesser rank than unsigned
    int, but I know all too well that the assertion is indefensible.

    But nobody who works for me would ever write code like that a second
    time, one way or the other...

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c /faq
     
    Jack Klein, Sep 2, 2003
    #5
  6. In article <>,
    Jack Klein <> wrote:

    > On Tue, 02 Sep 2003 06:19:51 GMT, Kevin Easton
    > <> wrote in comp.lang.c:
    >
    > > That's not true. Consider:
    > >
    > > #include <stdio.h>
    > >
    > > typedef unsigned short foo_t;
    > >
    > > foo_t do_thing()
    > > {
    > > return -1;
    > > }

    >
    > Sad to say, you are absolutely right and I was wrong.
    >
    > I would like to be able to say nobody in their right mind would write
    > code like this using an unsigned type of lesser rank than unsigned
    > int, but I know all too well that the assertion is indefensible.


    The code could be

    typedef <sometype> uint32;
    typedef <sometype> uint16;
    typedef <sometype> uint8;

    typedef uint16 foo_t;
    etc.

    And when the code was written, uint16 was unsigned int and everything
    was fine, but then someone switched to a different compiler, and now
    uint16 is unsigned short...

    I'd hope that a decent compiler gives a warning for the return
    statement, because it definitely doesn't return what you expect (on all
    five compilers that I can use easily it will return 65535). And another
    warning possibly on the comparison do_thing () == -1 because that could
    never be true (on the same five compilers).

    > But nobody who works for me would ever write code like that a second
    > time, one way or the other...
     
    Christian Bau, Sep 2, 2003
    #6
    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. kevin
    Replies:
    11
    Views:
    5,834
    Andrew McDonagh
    Jan 8, 2005
  2. mars
    Replies:
    2
    Views:
    291
    Gabriel
    Sep 9, 2005
  3. Replies:
    11
    Views:
    1,419
    James Kanze
    Jun 7, 2007
  4. Wally Barnes
    Replies:
    3
    Views:
    540
    Wally Barnes
    Nov 20, 2008
  5. Sosuke

    Up casting and down casting

    Sosuke, Dec 20, 2009, in forum: C++
    Replies:
    2
    Views:
    587
    James Kanze
    Dec 20, 2009
Loading...

Share This Page