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..