No that's backwards.eternal_noob Yep that should be the defaults in my opinion. It's ironic how many "weird little bugs" are actually fixed if you pay attention and correct compiler warnings.
Been a while since I looked but I think C++ treats int foo() like int foo(...) as Crivens points out. That may be relaxed or tightened in some versions of C++, I just don't recall any more.
K&R C was pretty lax and kind of assumed that hardware == VAX. Function declarations were not required and arguments would be promoted to int or double (there was certainly no long long back then, I'm not sure about long). Such implicit function declarations were assumed to have an int return type. In the time-honoured C programming tradition, this would then use the technique of "cross your fingers and hope that it works". If you were lucky the function call would actually match the function definition and not crash. Sophisticated K&R C programmers would declare their functions like "void * foo()". This at least means that the compiler now no longer has to guess the return type. It still means "any number and any type of arguments". That means argument matching still relies on crossed fingers.
ANSI C slightly upped the ante with function prototypes. That declares the function name return type _and the number and types of the arguments_. Coo! But you're still not entirely out of the woods. If by some error you have different prototypes seen by the definition and function call you will get no compiler or link error. That's because the object file symbol will be just "foo" without any information on the arguments. In this case you still need to cross your fingers at runtime.
C++ has always been much stricter.
There has never been any of this implicit declaration nonsense. There has never been any of this declaration/prototype nonsense. In C++ all types need to be declared before they are used. Including functions.
In C++ "void* foo()" means a function taking no arguments.
Linking in C++ is also safer than in C. C++ uses name mangling. That means that when compiling "void *foo()" the compiler will emit _Z3foov as the name. That will only link with a foo without any arguments.
Unfortunately even C++ requires a small amount of finger crossing. As far as I'm aware object file formats (ELF for unix-like, COFF for Windows and macho for macOS) are all fairly rudimentary and, as a consequence, so are link editors. Some things have been done to bodge object files to handle more needs (mangled names, mutliple text sections like .text._Z3fooIciEPT_T0_ for templates/inlined functions). But even still the link editor does not know about C++ function _return types_. (Maybe because of the difficulties in handling covariant return types).
If you want to detect these kinds of errors before your application crashes, you need to use a static analysis tool (clang-tidy, coverity etc) that can do whole program analysis.
Finally, all of this nonsense would probably not have been necessary in the first place if C didn't have promotions and implicit conversions. Most non-C-based languages that I know (and that's not a lot) do not need to include headers.