unsigned long long int data_size = 60123456 * 128 * sizeof(double); // trouble-some code
The type of destination unsigned long long int data_size =
is irrelevant to the product calculation 60123456 * 128 * sizeof(double)
.
Best to insure math is done using at least the size of the target type to avoid overflow. In OP's case, that implies a constant with LLU
.
There are 2 product calculations, each with their own type math.
60123456
is an int
or long
depending on int
range. Let us assume it is an int
.
60123456 * 128
is an int * int
. The math product 7695802368
exceeds 32-bit signed integer range, thus signed integer overflow or undefined behavior (UB) with a 32-bit int
.
If 60123456 * 128
did not overflow, says 64-bit int
, than the next multiplication would be * sizeof(double);
and so int * size_t
results in a size_t
type product.
Product calculation should use at least unsigned long long
math as below:
unsigned long long int data_size = 1LLU * 60123456 * 128 * sizeof(double);
// or
unsigned long long int data_size = 60123456LLU * 128 * sizeof(double);
// or
unsigned long long int data_size = 60123456;
data_size *= 128 * sizeof(double);
// or avoiding naked magic numbers
#define A_HEIGHT 60123456
#define A_WIDTH 128
unsigned long long int data_size = 1LLU * A_HEIGHT * A_WIDTH * sizeof(double);
The sizeof (double)
hints that code is attempting to find the size of some 2D-like structure. I'd expect code like the following. Notice the result type of sizeof
is size_t
, so the product math is done using at least size_t
math.
size_t data_size = sizeof(double) * 60123456 * 128;
printf("data_size= %zu\n", data_size);
See also Why write 1,000,000,000 as 1000*1000*1000 in C?
and my answer reasons not to use 1000 * 1000 * 1000 for applicable details..