The first issue is the impedance mismatch between the original language semantics and what is possible to represent in C.
Two examples are tail calls and continuations, that are hard to get right at C level, either requiring compiler extensions, longjmp/setjmp tricks, or a little bit of assembly.
Then there is the whole issue with undefined behaviour in C, introducing bugs that didn't exist on the original code.
Even if the generated code is clean today regarding UB, you cannot ensure that a new C compiler version won't be introducing such issues.
Having said this, there are languages like Eiffel and Nim, whose main backend relies on C compilers, instead of compiling directly to pure native code.
Skipping Objective-C and C++ here, because although they started as C pre-processors, their code was to be an extension to C and so their semantics also imply C semantics.
Compiling to some kind of IR, like LLIR is more sane.
Then you can do whatever you want with it, generate code in another programming language, machine code, or a plain interpreter for bootstrapping purposes.