In some ways, that's because C is a lower-level language, closer to assembly; it just gives you what the underlying machine gives you.
For example, Python integers behave like their mathematical counterparts. They are unbounded; adding integers will always give you the right answer, no matter how large. (Unless, of course, the computer runs out of memory. No language can conjure infinite resources. But it can and does guarantee that you will either get the right answer, or a crash. Never the wrong answer.)
C integers are what fits in a CPU register. The + operator performs a single CPU add instruction. If that overflows a machine word, it will give something other than the right answer. int successor(int a) { // May or may not be correct return a + 1; } (The association of C integers with CPU registers, necessarily glosses over complexity for the sake of brevity. For example, compilers targeting 32-bit platforms may provide 64-bit operations, implemented with runtime library support. Conversely, on 64-bit platforms, int is still usually 32-bit, for the historical reason that we spent too many years on 32-bit platforms; by the time the upgrade came, assumptions about the size of int were baked into too much code. If you want more details, Wikipedia provides a good start. The point here is that C is designed so basic operations compile to a small fixed number of CPU instructions, and that number is usually 1.)
In other ways, less intuitively, the difficulty arises because C is not simply high-level assembly, and does not always give you what the underlying machine gives you.