On 9/17/18 4:05 PM, Eric Blake wrote:


Also, ~((n)-1) is identical to -(n), if you want less typing (well, as long as you assume twos-complements signed numbers, but that's pretty safe to assume these days).

Nir is correct that the C standard states that ~, &, and | on signed values have implementation-defined behavior (it is only undefined once you move over to << and >>). If you are computing & or | where both values are positive, the results are well-defined. But if either operand is negative, you can get odd results. Similarly, ~ is always implementation-defined on signed (it is well-defined to flip all bits, but unless you know if the implementation defined ints as sign-magnitude, ones-complement, or twos-complement, you can end up with a different result than intended. If you don't want to assume twos-complement, then you could write it as:

~((n)-1U)

to force coercion to unsigned for most inputs, at which point ~ is well-defined. Except that (int64_t - 1U) doesn't coerce to unsigned. And you don't want to blindly write 1ULL to force 64-bit math everywhere, when the macro is otherwise fine on 32-bit inputs.

You can use the fact that '1 ? a : b' produces the expression 'a' coerced to the wider type of either 'a' or 'b'. And there's gcc's typeof operator, since you're already relying on extensions.

(Note, I'm trying to give you enough hints to be able to write a working patch, without submitting it myself, because I'm worried that I'm perhaps tainted license-wise on this particular issue since I patched a similar bug in qemu where the license does not permit wholesale copying over to nbdkit)

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

_______________________________________________
Libguestfs mailing list
Libguestfs@redhat.com
https://www.redhat.com/mailman/listinfo/libguestfs

Reply via email to