Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

32 bit unsigned multiply on 64 bit causing undefined behavior?

People also ask

Are integers 32 bit or 64 bit?

int is 32 bits in size. long , ptr , and off_t are all 64 bits (8 bytes) in size.

Are integers always 32 bit?

The size of a signed int or unsigned int item is the standard size of an integer on a particular machine. For example, in 16-bit operating systems, the int type is usually 16 bits, or 2 bytes. In 32-bit operating systems, the int type is usually 32 bits, or 4 bytes.


The simplest way to get the multiplication to happen in an unsigned type that is at least uint32_t, and also at least unsigned int, is to involve an expression of type unsigned int.

v = 1U * s1 * s2;

This either converts 1U to uint32_t, or s1 and s2 to unsigned int, depending on what's appropriate for your particular platform.

@Deduplicator comments that some compilers, where uint32_t is narrower than unsigned int, may warn about the implicit conversion in the assignment, and notes that such warnings are likely suppressable by making the conversion explicit:

v = (uint32_t) (1U * s1 * S2);

It looks a bit less elegant, in my opinion, though.


Congratulations on finding a friction point.

A possible way:

v = (uint32_t) (UINT_MAX<=0xffffffff
  ? s1 * s2
  : (unsigned)s1 * (unsigned)s2);

Anyway, looks like adding some typedefs to <stdint.h> for types guaranteed to be no smaller than int would be in order ;-).