C is, essentially, a good portable assembler. It's barely a compiler at all, which is why it could fit on really small 8-bit systems.
For that matter, Byte once ran an article where they implemented most of C in M68000 assembler macros, so that it ACUTALLY was assembler. It wasn't all of C, just most of it, and it was too clumsy to actually use (M68000 assembler code was as readable and much more efficient), but it worked.
For that matter, LifeboatC, an i8080 compiler, really was a translator from C to assembler (a translator, not exactly a compiler) to the point that if you knew what you were doing you could drop assembler instructions in the middle of your C code and have them work properly. It emitted assembler code or (I believe, it's been awhile) could directly build an executable. But C is much more similar to M68000 assembler than i8080 assembler, so LifeboatC was rather of a tour de force. It wasn't a full K&R C, but it was quite close.
So I consider C a portable assembler, and as such quite good. I don't think of it as a good compiler language. At this point in time a good computer language needs to handle unicode characters quite well. Vala has potentials, if it ever matures. Similarly D (Digital Mars D) has potentials. If you don't need speed, Python is a good choice. Soon a good computer language will also need to handle parallel processing gracefully...but so far I haven't seen any contenders for this. Even C will do it if you don't demand grace and elegance.
P.S.: I no longer consider assembler a reasonable thing to require...either of myself or of anyone who isn't implementing things at the hardware level. C is as close to that as I consider reasonable, and even C is limiting. The complexity of code anyone can write is limited, so any complexity you can push off onto your tools should be so pushed...unless you are a tool designer or builder, or, to a much lesser extent, evaluator.