On 12/11/2017 09:24 AM, Vladimir Sementsov-Ogievskiy wrote:

>> On the other hand, '<< BDRV_SECTOR_BITS' only produces the same size
>> output as the input; if the left side is 32 bits, it risks overflowing.
>> But '* BDRV_SECTOR_SIZE' always produces a 64-bit value.  So I've
>> learned (from past mistakes in other byte-conversion series) that the
>> multiply form is less likely to introduce unintended truncation bugs.
> 
> hm, now I doubt. I've wrote tiny program:
> 
> #include <stdint.h>
> #include <stdio.h>
> 
> int main() {
>     uint32_t blocks = 1 << 20;
>     int block_bits = 15;
>     uint32_t block_size = 1 << block_bits;
>     uint64_t a = blocks * block_size;
>     uint64_t b = blocks << block_bits;
>     uint64_t c = (uint64_t)blocks * block_size;

Not the same.  'block_size' in your code is 'uint32_t', so your
multiplication is still 32-bit if you don't cast blocks; while qemu has::

include/block/block.h:#define BDRV_SECTOR_BITS   9
include/block/block.h:#define BDRV_SECTOR_SIZE   (1ULL << BDRV_SECTOR_BITS)

and the 1ULL in the qemu definition forces 'unsigned long long' results
whether or not you cast.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to