This is interesting, but I wouldn't say it is valid C. main() doesn't know about greet(auto s) and wouldn't be able to call it in valid C89, right?
It's valid K&R since everything defaults to int. The linker will match the symbols sans prototype. That wasn't obsoleted until C23.
It is valid C89. greet is automatically declared as
int greet();
It's valid K&R since everything defaults to int. The linker will match the symbols sans prototype. That wasn't obsoleted until C23.