[Tinyos-help] Bug in NesC or a simple error.........???

David Gay dgay42 at gmail.com
Mon Jan 29 10:15:43 PST 2007


On 1/26/07, Miguel Pereira <miguelpereira.pro at gmail.com> wrote:
> Hi,
>
> Your are right! I put 65535UL and the warning disappear. Although I think
> should not be necessary to add UL to the number. If the variable is uint32_t
> should handle with the number 65535 without UL.

The warning is correct. The C standard specifies the result type of
operations like /, +, etc based on the type of the arguments, not on
the type of where the result is eventually used. So in:

  int16_t a, b;
  int32_t c;

  c = a * b;

The multiplication is a 16-bit multiplication, not a 32-bit one. It's
easy to get caught by this, especially on platforms with 16-bit ints.
For instance,

  int32_t x = 1 << 24;

will give you x == 0 on an atmega128 (or msp430, etc) (the type of 1,
24 is int, i.e. int16_t in this case, the type of << applied to two
int16_t's is int16_t).

In the case of
  uint16_t random;
  uint64_t result = (uint64_t) ( ((1000)*random) /65535);
we have:
  1000*random:
    int16_t * uint16_t -> result is uint16_t

  (1000*random)/65535): this one is complex:
    - the first argument is uint16_t.
    - the 2nd argument (65535) is trying to be an int (you didn't use
U or L as suffix), but doesn't fit within a 16-bit integer (hence the
warning you don't like) so it's treated as a uint16_t
    - the result is an uint16_t (we're dividing two uint16_t's)

  (uint64_t) ( ((1000)*random) /65535):
    we're casting a uint16_t to a uint64_t (note that this cast is
useless, as the conversion to uint64_t would happen in the assignment
anyway)

  uint64_t result = (uint64_t) ( ((1000)*random) /65535);
    we're assigning a uint64_t to a uint64_t

David Gay
PS: Who said C was simple?


More information about the Tinyos-help mailing list