As buttiful butterfly correctly points out, the aim of the c++ language and standard library design is to enforce logical correctness at compile time.
What this means is that we aim for a situation where a program that would do the wrong thing under certain obscure circumstances simply will not compile (or will compile, but will warn you).
This means you can fix these logical errors before your software ever even runs in your test harness, let alone in front of your customers.
The result of this is that correctly written c++ code can be mostly proven to be 'correct' before run-time, meaning you spend a great deal less time tracking down obscure bugs that you otherwise would.
The magic of c++ is that is performs this incredible feat while offering a fantastic of efficiency and code optimisation.
note: by 'correct' I mean that it will reliably do what you think you're telling it to do. It's still up to you to write the correct logic!
as to the questions:
So my question is why does C define so many incompatible types instead of simply using primitive types such as int short ...? It's not user-friendly at all.
They are made incompatible in order to deliberately prevent you from converting them to each other. They represent different concepts, in the same way that velocity and distance are different concepts. There is no direct conversion between them.
And how can I do arithmetic operations on these types?
make the intermediate results of your arithmetic something that these types can safely convert to without losing precision. In this case, tv_sec and tv_usec are integral types, so even though they are incompatible with each other, they are both convertible to double individually.
for example:
double mytimer(struct timeval *start, struct timeval *end)
{
return double(end->tv_sec - start->tv_sec) +
double(end->tv_usec - start->tv_usec) * 1e-6;
}