Variable declaration in function prototype and in block code : difference?

what is the main difference between a function declaration and a function definition
difference between function signature and function prototype
difference between function declaration and function definition in c programming
function prototype c++
function declaration syntax
function declaration in c
difference between function definition and function declaration in hindi
function header in c

Why int array[] raise a compilation error in main but not in function prototype ? Should it mean that it is better to always write int * array in function prototype ?

void myfoo (int array[]) { // No compilation error
;}

void myfoo1 (int *array1) { // No compilation error
;}

int main() {
    int array[]; // Compilation error
    int* array1; // No compilation error
}

Fundamentally, the reason an array declaration inside the block for main needs a size and the array declaration in the function parameter does not is that the declaration in main is defining an array, whereas the function parameter is merely receiving an array that something else defines.

So the definition in main needs a size because it must reserve storage for the array.

The function parameter is merely receiving an array, so it only needs to know where the array starts. It does not need to know the size. (That is, the compiler does not need to know the size in order to compile the code. The function may need to know the size in order to perform its intended purpose, but that is a matter for the programmer, not the compiler.)

Due to C rules, arrays can never actually be passed as function arguments. Whenever an array is given as a function parameter, the compiler automatically converts it to a pointer to its first element. Similarly, a function parameter can be a pointer but cannot actually be an array. When you declare a function parameter as an array, the compiler automatically adjust it to declare a pointer instead. So the function declaration void myfoo(int array[]) is automatically adjusted to be void myfoo(int *array).

The specific rule that requires the declaration in main to have a size is C 2018 6.7 7:

If an identifier for an object is declared with no linkage, the type for the object shall be complete by the end of its declarator, or by the end of its init-declarator if it has an initializer;…

What is the difference between declaration and definition of, definition is associating the task or the meaning with the prototype. When we declare the variable we using extern keyword, and decalretion is do outside the main() function. int a; ///inside a block it is both definition and declaration The function definition contains the whole data and the code or methods of that function  A Function prototype is a declaration of a function that declares the types of the function’s parameters and defines them. A Function definition defines the function itself. It also acts as a declaration, and if the declaration includes the types of its parameters, a prototype as well.

In your code, inside the function, writing int array[]; for an array definition is a semantic error.

In this case, array is a variable with no linkage, ("a block scope identifier for an object declared without the storage-class specifier extern") and as per the spec:

If an identifier for an object is declared with no linkage, the type for the object shall be complete by the end of its declarator, [....]

An empty [] (with or without space(s) in between), does not make a valid construct for an array definition, as the size of the array remains unknown (Notice the lack of an explicit brace-enclosed list of initializer, too). Thus, your compiler complains, as the type is not complete and it has no idea of the total amount of memory to be reserved for that array variable.

On the other hand, for function parameters, an array type parameter actually decays to a pointer to the type, so, specifying the array size is not mandatory. Quoting chapter §6.7.6.3

A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’, where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. [...]

and

If the function declarator is not part of a definition of that function, parameters may have incomplete type and may use the [*] notation in their sequences of declarator specifiers to specify variable length array types.

So, basically, a statement

 void myfoo (int array[])

is equivalent as

void myfoo (int *array)

so, this is accepted by compiler.

User-Defined Functions for C++, The function prototype and the function definition must agree EXACTLY on the return type, the name, and the parameters. The only difference between the function  I'm going through this C code and the function declarations seem to contain block comments. they look like this: void show_rank (/*in*/ Rank rank); is that actually a block comment in the arguments or does it have an alternate meaning? The variable R

void myfoo (int array[]) { // No compilation error
;}

It means myfoo() will be called with an integer array (of any size). Compiler can just compile it.

void myfoo1 (int *array1) { // No compilation error
;}

It means myfoo1() will be called with a pointer to integer. Compiler can just compile it.

int main() {
    int array[]; // Compilation error
    int* array1; // No compilation error
}

int array[];

This is the definition of the array. But the compiler can not determine the size of the array. So it does not know how much memory to be allocated. So you have to provide either size or initialize it with some values as below.

int array[3];

or

int array[] = {1,2,1};

.

int* array1;

This is just a declaration of integer pointer. Nothing wrong in it and compiler can compile it.

C Programming Course Notes - Functions, It is also common to need the same code in multiple different programs. Note also that the variable names are not required in the function prototype. local variables are declared inside of a function, and outside of any braced blocks such  Difference between Definition and Declaration Declaration of a variable is for informing to the compiler the following information: name of the variable, type of value it holds and the initial value if any it takes. i.e., declaration gives details about the properties of a variable.

Scope rules in C, Function Prototype Scope, Identifiers declared in function prototype are visible within the prototype This statement accesses only outer block's variables. In C++, a function must be declared and defined before it is used (called) anywhere in the program. C++ Function Prototype. A function prototype is a declaration of the function that tells the program about the type of the value returned by the function and the number and type of arguments.

Function Prototypes, A function prototype is a function declaration that specifies the data types of its in a function prototype to ensure that the corresponding function definition and all Ellipses are used in the parameter list of a prototype to indicate that a variable call only if the prototype is specified within the same block as the function call,  Function prototype declaration is necessary in order to provide information to the compiler about function, about return type, parameter list and function name etc. Important Points : Our program starts from main function.

Function Declaration, The SISAL compiler generates optimized C code as its intermediate A function declaration is a function definition if the function prototype is also followed A local variable declared at block scope normally has an automatic storage duration. Declaration vs. definition. One basic dichotomy is whether or not a declaration contains a definition: for example, whether a declaration of a constant or variable specifies the value of the constant (respectively, initial value of a variable), or only its type; and similarly whether a declaration of a function specifies the body (implementation) of the function, or only its type signature.

Comments
  • The compiler in your main needs to know how much memory to allocate for your array on stack as it is save as a continuous block. allocating a int* allocates size of (pointer) on stack . Your function can get an address to an array, but you will not be able to know its size unless you send it as a variable to the function as well. when you send a var to a function by value- the int* makes room for an int pointer type only, not the hole array.
  • Is void myfoo(int array[])is automatically adjusted to void myfoo(int *array ) or void myfoo(int (*array) ) ? See my last comment @Sourav,
  • @Stef1611: void myfoo(int *array) and void myfoo(int (*array)) are the same thing.
  • In this case, I agree but I should have added a word like "strictly". I do not how to link a comment so I do a copy : I know that an array decays to a pointer but what bothers me is that you could use array [] in prototype. Is void myfoo (int array[]) strictly equivalent to void myfoo (int *array)? For example, you could write myfoo (int array[][2]) and it runs but myfoo (int *array[2]) compiles but does not run. You have to write myfoo (int (*array)[2]). Is it only a question of operator precedence or are there some hidden subtilities ?
  • I agree with all the answers but why you could use int array [] to declare a POINTER in the function prototype and not in a block of code.
  • @Stef1611 Because, as I mentioned, in case of a function argument, the array decays to a pointer, so the array size is optional. However, inside block of code, an array and a pointer are different types and they have different properties.
  • @Sourav Ghosh. I know that an array decays to a pointer but what bothers me is that you could use array []in prototype. Is void myfoo (int array[]) strictly equivalent to void myfoo (int *array)? For example, you could write myfoo (int array[][2]) but myfoo (int *array[2]) compiles but does not run. You have to write myfoo (int (*array)[2]). Is it only a question of operator precedence or are there some hidden subtilities ?
  • @Stef1611: int array[][2] is an array (of unknown size) of arrays of two int. Since it is an array, when it is a function parameter declaration, it is automatically adjusted to be a pointer to an array of two int, which is int (*array)[2]. If you wrote int *array[2], that is different; that is an array of two pointers to int. Yes, it is just operator precedence here that is requiring the parentheses. [] bind more tightly than *, so, when changing an array array[] to a pointer, you need to add parentheses to keep them together, (*array).
  • @Stef1611: Thus, you could also say int array[] becomes int (*array). It is just that, in that case, there is no other operator included, so the parentheses do not happen to be needed. In int array[][2], you need to use parentheses to keep the * with the array.
  • void myfoo(int array[]) does not mean myfoo will be called with an integer array. In a function declaration, an array parameter is automatically adjusted to be a pointer. Thus void myfoo(int array[]) becomes void myfoo(int *array), and the array is called with a pointer to an int.