I don’t think anybody thinks or thought it was.
I thought it would be, given that C is designed in such a way that a single pass ought to be sufficient. Single-pass compilers were not uncommon in that era.
Was it really designed this way? I keep hearing this claim but I don't think Ritchie himself actually confirmed that?
Also, notice how the functions call each other from wherever, even from different files, without need of any forward declarations, it simply works, which, as I have been repeatedly told, is not something a single-pass compiler can implement :)
I mean, I don't know if it was ever explicitly stated, but consider: parsing requires at most one token of lookahead - assuming that you use the lexer hack to disambiguate declarations; and in earliest versions of C without typedef, you don't even need the hack because all declarations must start with a keyword. You cannot reference any declarations - not types, not variables, not functions - until they are defined, with a special exemption for pointer types that is precisely one case where the compiler doesn't care because a pointer is a pointer. Altogether, C design permits and even encourages a naive implementation that literally does a single pass parsing and emitting highly unoptimal, but working assembly code as it goes (e.g. always use stack for locals and temporaries). There's also stuff like "register" which is incredibly useful if you're only doing a single pass and of very dubious utility otherwise. I find it hard to believe that it is all a happy coincidence.
Regarding functions, it only works if the function returns int and you match the types correctly for any call that doesn't have the prototype in scope. I believe this to be one of the relict B compatibility features, BTW, since that's exactly how it also worked in B (except that int is the only type there so you only had to match the argument count correctly).