Re: Style question: comparison between signed and unsigned?

nospam-seesignature@ceddec.com
Tue, 23 Sep 1997 12:52:55 -0400


On Mon, 22 Sep 1997, Linus Torvalds wrote:

> sizeof() returns a size_t, which is unsigned, but that's also exactly what
> read() wants as the argument.
>
> And read cannot return any value outside an "int", because it's
> constrained by the size of the read (plus the special value "-1"). So the
> statement
>
> int i = read(socket, buffer, sizeof(buffer));
>
> is not only the common way to do this, it's also the _correct_ way to do
> this.
>
> Now, the PROBLEM is somewhere else (and is a problem that is not dependent
> on the size, but purely on the signedness of the types - so even if "i"
> had been ssize_t the same problem would happen): the part of the code
> snippet that you edited out. This was:
>
> /* check for errors *?
> if (i == -1)
> return i;
>
> /* check that we got a valid packet */
> if (i < sizeof(struct pkthdr))
> return SHORT_PACKET;
>
> Now, the PROBLEM is that if gcc warns about signed/unsigned comparisons
> (which some versions of gcc do), gcc will totally needlessly (and in my
> opinion incorrectly) warn about the second test (ie "i < sizeof(struct
> pkthdr)"). Because "i" is signed, but "sizeof" is unsigned.

sizeof is misimplemented. Usually I have seen this handled as

#define BUFFERSIZE 1024

unsigned char buffer[BUFFERSIZE];

i = read(... buffer, BUFFERSIZE);

if( i < BUFFERSIZE )...

gcc manages not to complain about this because with 1024 being a const, it
knows whether it will fit into an int - it doesn't have signed-unsigned as
an attribute. Neither should sizeof, but it is a pretend function, so
instead of converting sizeof(buffer) to a constant of 1024 and then
worrying about type conversion, it says sizeof is unsigned and does a
check then.

Something like:

extern unsigned char x[];

void t()
{
int i;

i = sizeof(x);

}

fails with "sizeof applied to an incomplete type" since it really must be
a const. If sizeof was treated like numeric constants it would work (I
haven't checked const unsigned int x = 1024; - it probably does the wrong
thing too).

--- reply to tzeruch at ceddec dot com ---