although the caller of test_print in main has different amount of arguments with the defination of this function, the code can work very well, but if change it into c++ version, there occurs a compile error "too many arguments to funciton ....".
why C allows argument mismatch call of function, when can we use this way of calling? and why it's forbidened in c++.

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

In C99 this invokes undefined behavior. See: C99 6.5.2.2/6 If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions. If the number of arguments does not equal the number of parameters, the behavior is undefined.
–
cpxDec 26 '12 at 6:48

you have not provided a prototype for the function, so the compiler is not supposed to compare calls with the argument list. To provide a prototype, you have to write an explicit void:

void test_print(void) { ... }

Or provide a separate prototype declaration:

void test_print(void);

But it is best to make the function definition match the prototype declaration, so always write the void. And yes, this is one of the areas where C++ differs from C. You can't use a function in C without a prototype in scope and C++ is able to treat an empty argument list as an empty argument list. In C99 or later, you're supposed to have a prototype in scope, but it isn't usually enforced by the compiler unless you add more stringent options (-Wmissing-prototypes -Wstrict-rprototypes -Wold-style-definition -Wold-style-declaration are possible GCC options). But the backwards compatibility requirements with pre-standard C meant that C89 could not enforce the 'empty parentheses means no arguments' rule without breaking a lot of previously valid C code, which would have prevented the standard from being acceptable.

It is a good programming discipline to ensure that you find the compiler option that ensures that all functions are declared with a full prototype before being used, and to ensure that you use the compiler option all the time, and heed its warnings