In C++ (as well as in C), parameters declared with array type always immediately decay to pointer type. The following three declarations are equivalent
void printValues(int nums[3], int length);
void printValues(int nums[], int length);
void printValues(int *nums, int length);
I.e. the size does not matter. Yet, it still does not mean that you can use an invalid array declaration there, i.e. it is illegal to specify a negative or zero size, for example.
(BTW, the same applies to parameters of function type - it immediately decays to pointer-to-function type.)
If you want to enforce array size matching between arguments and parameters, use pointer- or reference-to-array types in parameter declarations
void printValues(int (&nums)[3]);
void printValues(int (*nums)[3]);
Of course, in this case the size will become a compile-time constant and there's no point of passing length
anymore.