Pregunta

So, I have the following code, I know it is broken somewhere and I simply cannot identify where...

static uint64_t get_disk_total(const char* path)
{
    struct statvfs stfs;
    if ( statvfs(path, &stfs) == -1 )
    {
        return 0;
    }
    uint64_t t = stfs.f_blocks * stfs.f_bsize;
    std::cout  << "total for [" << path << "] is:" << t 
               << " block size (stfs.f_bsize):" <<   stfs.f_bsize
               << " block count (stfs.f_blocks):" << stfs.f_blocks 
               << " mul:" << stfs.f_blocks * stfs.f_bsize
               << " hardcoded: " << (uint64_t)(4096 * 4902319)     // line 50
               <<  std::endl ;
    return t;
}

When I compile it, tells me:

part_list.cpp: In function ‘uint64_t get_disk_total(const char*)’:
part_list.cpp:50:59: warning: integer overflow in expression [-Woverflow]

Good. And when I run it, the result is (line breaks added manually):

total for [/] is:2900029440 
block size (stfs.f_bsize):4096 
block count (stfs.f_blocks):4902319 
mul:2900029440 
hardcoded: 18446744072314613760

I know, that 4902319 * 4096 = 20079898624 ... google tells me it is. So how on earth do I get firstly 2900029440 and then 18446744072314613760 for the same calculation? Can someone please explain me what is happening here? It is above my comprehensive capabilities right now, and I feel, this is a tiny tiny issue somewhere hidden... 4902319 * 4096 should not be such a huge number for the application to go crazy like this...

Thank you for your help!

¿Fue útil?

Solución

First you calculate (4096 * 4902319) which is calculated as int and it overflows. Then that number is converted to uint64_t.

Try:

(4096 *  (uint64_t) 4902319) 

To make it calculate as uint64_t.

Otros consejos

Use Unsigned long long literal :

   4096 * 4902319ULL
                 ~~~

Before the calculation overflows.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top