types, constants and casting

T

Tom Carroll

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
 
J

Jack Klein

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
 
J

j

Tom Carroll said:
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. ''
 
K

Kevin Easton

Jack Klein said:
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.


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

- Kevin.
 
J

Jack Klein

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
 
C

Christian Bau

Jack Klein said:
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).
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top