You cannot return an array, as such, from a function in C (or C++).
What your code currently does is: it implicitly decays the int[] array to an int* pointer, and then implicitly casts the int* to a long, and then returns the long. This is not a pointer or an array, and thus the subscript operator may not be applied to it.
You could return an int*, but returning a pointer to the local arr array would be wrong (your compiler might not be able to catch the error, but you will invoke undefined behaviour at runtime) because as soon as the function finishes, arr officially does not exist and the returned pointer is therefore dangling.
You can:
allocate an array with malloc() and return the pointer (but then you have to figure out who is going to free() the allocation, and make sure that happens exactly once); or
pass in a pointer to an array, and populate the array via that pointer (now the caller is responsible for creating and managing the array) - this is probably the usual approach in C; or
create a struct that wraps an array, and return one of those (or, for that matter, pass in a pointer to one).
Also note that int arr[ceiling + 1]; is a C99 construct; it is not allowed in standard "traditional" C (C89 etc.), nor in standards-compliant C++. In those languages, the size of arrays must be known at compile-time.
In C++ you could also pass an array by reference, or use boost::array (which is "a struct that wraps an array", but also uses operator overloading to make it behave more transparently like an array).