Standard C provides two ways of declaring functions. The modern way, called a prototype, declares the types of the parameters. For example, void foo(char a, float b);. The old way does not include the parameter types. For example, void foo();.
In the old method of declaring functions, integer arguments narrower than int are passed as int (or, in certain cases, as unsigned int), and float arguments are passed as double. This arose largely because of the circumstances in which C developed and the flexibility with which it handled small integers.
If you call a function declared with a prototype, the C implementation knows the types of the parameters and converts each argument to the destination type. If you call a function declared without a prototype, the C implementation does not know the true types of the parameters in the function definition, but it knows that narrow integer types must be passed as int (or unsigned int) and float arguments must be passed as double. So any arguments of these types are converted to int, unsigned int, or double, as appropriate.