Q:

Passing array as a parameter with its size inside brackets

Is defining a function this way legal or helpful in any way? 
void f(int arr[ARR_SIZE])

A:

It's legal (assuming that ARR_SIZE is a positive integral type), and is perhaps a useful annotation, although confusing as it seems to make a false promise.  On balance I wouldn't use it. 
It doesn't mean that arr is an array of that size: arr is still an int* (due to pointer decay) and all size information is lost. 
Far better then to write
void f(int* arr, size_t n)

with f(arr, ARR_SIZE) at the calling site, or f(arr, sizeof(arr)/sizeof(arr[0])) if the non-decayed type of arr is available.