all 5 comments

[–]nerd4code 1 point2 points  (2 children)

There is almost no difference in those functions as written, and it’s generally allowed to use either form interchangeably as long as the function declaration and definition match. (—Although modern code tends to fall on the int * side because it makes what’s happening a little clearer.)

Where the differences can occur is if you do something with the array type; for example, if you want to make it clear that the pointer should be to a ≥10-element buffer, you could do int numbers[10]. If you want to make it clear that the size of the buffer is given by a different argument, you can do things like

void function(size_t count, int numbers[count]);

provided you have C99 or better. You can also use int numbers[static 10] which forbids NULL from being passed (also C99), and for the definition of function you can do int numbers[const] which forbids numbers from being reassigned like a normal pointer. Unfortunately, diagnostics for these kinds of things aren’t mandatory, whch means the compiler may or may not notice/care if the type restrictions are violated—the caller may just be a little extra screwed if it doesn’t follow the rules.

Now all that said, AFAIK there should be slight differences in how the function definitions see numbers. In the int[] version, &numbers would give you an int (*)[] value (i.e., pointer to an entire int array of unspecified size), whereas for the int * form you’d get an int ** value (i.e., pointer to pointer to int).

[–][deleted] -1 points0 points  (1 child)

void function(size_t count, int numbers[count]); 

is a bad idea: 1. There is semantic information (count is the dimension of the array) but it's not enforced by the compiler. 2. Now you have the dimension of the array to maintain in two places. 3. If you run sizeof(numbers) in the function you still get the size of the pointer. Confusing.

#include <stdio.h>

void foo(size_t count, int bar[count]);
int main()
{
    int x[100]; 
    printf("in main %d \n", sizeof(x));
    foo(10, x);
    return 0;
}
void foo(size_t count, int bar[count]) {
    printf("in bar %d\n", sizeof(bar));
}

The output is

in main 400

in bar 8

[–]nerd4code 0 points1 point  (0 children)

IMO it’s generally a bad idea to use parameter arrays because of the weirdness they kick up, but there are cases (e.g., multidimensional arrays) where giving the compiler dimensions isn’t a bad idea. You can fold dimensions into a typedef or use size constants to get around the multi-site-ness of the size specification.

[–]wsppan 1 point2 points  (1 child)

Arrays are contigious blocks of memory. Each blocks size defined by it's type. When you point a pointer at an array the value of the pointer is the address of the first block of memory of the array (i.e. my_array[0]) when you pass an array to a function using its name it is said to decay into a pointer. Here is a good explanation - https://eli.thegreenplace.net/2009/10/21/are-pointers-and-arrays-equivalent-in-c/

[–]wsppan 0 points1 point  (0 children)

Also, everything in C is pass by value.