Re: Why is this cast nessasary



Keith Thompson wrote:
Neil <NeilKurzm@xxxxxxxxxxxxxxxx> writes:
Question

should this cast be necessary?
The Compiler is 8 Bits the ints are 16 bits.

I don't know what you mean by "The Compiler is 8 Bits". I'll assume
char is 8 bits (CHAR_BIT==8) and sizeof(int)==2.

The Code is for a ring buffer

It does not work without the cast in this compiler.

It's impossible to tell what you mean by "does not work". Does it
fail to compile? Does it give you different results than the ones you
expected? What did you expect, and what did you get?

I have seen it work else where without it.
Which way is right (or should it matter at all?)

[...]
.
unsigned char t_in;
unsigned char t_out;

/*----------------------------------------------------------------*/
bit com_putchar (unsigned char c)

Presumably "bit" is declared somewhere.

{

/*If the buffer is full, return an error value.*/
if ((TBUF_SIZE - (unsigned char)(t_in - t_out)) <= 2)

Likewise TBUF_SIZE.

In an expression, any subexpression of type unsigned char is going to
be promoted to either int or unsigned int. It will be promoted to int
if int can hold all possible values of type unsigned char (which is
almost always the case).

So t_in - t_out is of type int, and it could be either positive,
negative, or zero. The conversion to unsigned char yields a positive
or zero result. For example, if t_in - t_out is -1, the conversion
probably yields 255.

You then subtract that result from TBUF_SIZE, but we have no idea of
the value, or even the type, of TBUF_SIZE.

That's about all I can tell you.

return (1);

/* More Code */
[...]
return (0);
}

A minor style point: The parentheses on the return statements are not
necessary. They're harmless, but I (and, I think, most c programers)
prefer:
return 1;
...
return 0;


Sorry I was Not complete:
8 bit as in PIC16 CPU not a PC. 8 bit char and 16 bit ints
bit is actually a bit, but I assume it does not matter.

TBUF_SIZE Assume 32 for this purpose.

The parentheses I try to keep the code uniform. the original must have had them.

Does not work means compiles, but does not work as expected. The math does not work as the ring buffer wraps. The full buffer is not detected and the data is over written.

So it could be an integer promotion issue (that would make sense in this case). The one other Compiler has a none standard No promote option. And the second was for a 32 bit compiler using unsigned longs

I hate fix something without understanding the fix, or complain about the compiler when it doing the right thing. I could look at it again and see if the compiler matches the math if it is all promoted.
.



Relevant Pages

  • Billys Silly Things - Demo and Childrens Activity for DOS 3.3
    ... The compiler and tools will be updated shortly to include this demo ... unsigned char sillyname; ... int bottom = 0; ...
    (comp.sys.apple2.programmer)
  • Re: Visual C++ aliasing issue
    ... The compiler optimizes the variable out however. ... struct Pixel3; ... struct Pixel4 {unsigned char b, g, r, a;}; ... int iSrcBytesPP = 3; ...
    (microsoft.public.vc.language)
  • Re: It Pays to Enrich Your C Skills
    ... Check if you can score a perfect 10 (without using a compiler). ... int main{ ... struct bitfield { ... out if it is a negative integer constant or a constant expression ...
    (comp.lang.c.moderated)
  • OT: Re: Perl Peeves
    ... I see the result of a test being used as an int. ... the compiler just assumed you knew what you were doing ... introduced to the language later, so void * was unheard of in most code. ... This didn't mean bool was special, declaring it just signaled to the ...
    (comp.lang.perl.misc)
  • Re: OT: Re: Perl Peeves
    ... when I see the result of a test being used as an int. ... compiler just assumed you knew what you were doing and would ... This didn't mean bool was special, declaring it just signaled to the ... What "normalization of bool results is built into the compiler"? ...
    (comp.lang.perl.misc)