Function declaration - c

int func(void) [5];
Why is above line not valid in c ? As anyone knows, function can be used as variable. But, I don't understand why compiler gives error .
Why I used that line is because I have tried to create 5 function-variable. To do so, I wrote like that, shown above.

Because it doesn't meet the C language valid syntax?
May be you should specify what are you trying to do with that sentence in order to get the answer you might be looking for.

This is not legal C syntax, period.
It is invalid in C++ too because functions cannot be put in arrays (you are trying to declare an array of five functions). However, the following works both in C and C++:
int (*func[5])(); // C++ version
int (*func[5])(void); // C version
and declares an array of five function pointers.
If you instead want a function which returns an array, in C you do
int *func(void);
and in C++ you do
int* func();
or
int (&func())[5];
which returns a reference to an array of five integers.

From the C standard (n1256):
6.7.5.3 Function declarators (including prototypes)
Constraints
1 A function declarator shall not specify a return type that is a function type or an array
type.
Functions cannot return array types or other function types. Functions can return pointers to those types, though:
int (*func(void))[5];
The syntax is a little weird looking, but it breaks down as follows:
func -- func
func(void) -- is a function taking no parameters
*func(void) -- returning a pointer
(*func(void))[5] -- to a 5-element array
int (*func(void))[5] -- of int
This isn't as useful as it looks: if you try to return a pointer to a local array, such as
int (*func(void))[5]
{
int arr[5] = {0,1,2,3,4};
return &arr;
}
the array no longer exists when the function returns; the pointer value you get back won't point to anything meaningful anymore.
If you're trying to create an array of functions, you have a similar problem; you cannot have an array of function types (6.7.5.2, paragraph 1, which includes the sentence "The element type shall not be an incomplete or function type"), although you can have an array of pointers to functions:
int (*func[5])(void);
This breaks down as
func -- func
func[5] -- is a 5-element array
*func[5] -- of pointers
(*func[5])(void) -- to functions taking no parameters
int (*func[5])(void) -- and returning int
Example:
int f0(void) { return 0; }
int f1(void) { return 1; }
int f2(void) { return 2; }
int f3(void) { return 3; }
int f4(void) { return 4; }
int main(void)
{
int (*func[5])(void) = {f0, f1, f2, f3, f4};
int i;
for (i = 0; i < 5; i++)
printf("f%d = %d\n", i, (*func[i])()); // or just func[i]()
return 0;
}

It is trying to declare a function that returns an array. This is not allowed - and it's nothing to do with syntax, it's a semantic rule, as demonstrated by the following (which has exactly the same problem, but is obviously syntactically fine):
typedef int FiveInts[5];
FiveInts func(void);
This is part of the "arrays are special" type rules in C. Function return values are not lvalues, and the only context in which a non-lvalue array could be used is as the subject of the sizeof operator. This makes functions returning array types completely useless.

try :
int *func(void);

Related

Understanding a pointer function that returns a pointer to an array

So, I am just trying to wrap my head around "pointer function that returns a pointer to an array"... but to start off slowly, I had to understand this:
void Print(const char c){
printf("\nPrint: %c\n", c);
}
int main () {
void (*FunctionPointer)(const char);
FunctionPointer = &Print;
FunctionPointer('a');
}
Which I do - pretty easy to guess what is going on... FunctionPointer just points to the location where the Print function "resides". Instead of jumping to a specific memory address (stored on a register) of a specific function, I can now be more flexible and point to any function that I want to access.
But I am stuck with the following...
int main () {
int (*FunctionPointer())[];
}
Now it seems that the function that is pointed by FunctionPointer, can in fact return a pointer to an array of type int. The compiler accepts the second line - so far so good - and I also understand the concept... but I am getting stuck regarding the implementation.
FunctionPointer needs - once again, to point to a function. That function can indeed return a pointer that points to an array of type int... soooooo:
int *Array(){
int ar[2] = {5,6};
return ar;
}
int main () {
int (*FunctionPointer())[];
FunctionPointer = &Array;
}
However, the last piece of code is just not accepted by the compiler.... So, what gives?
With
int (*FunctionPointer())[];
you've declared FunctionPointer as a function returning a pointer to an array of int -- not a function pointer. You want
int *(*FunctionPointer)();
If you use [] here, you'll get an error, as functions can't return arrays -- arrays are not first class types -- and unlike with function parameters, arrays will not be silently converted to pointers when used as the return value of a function type. With that, you'll still get the warning
t.c:3:12: warning: function returns address of local variable [-Wreturn-local-addr]
return ar;
^~
which is pretty self-explanatory
You have declared the array of function pointers. Arrays can't be assignable. Functions can't return arrays. You might wish
int* (*FunctionPointer)();
FunctionPointer = &Array;
Function pointers are much easier when you use typedefs. You can simply use the same notation as "normal" data pointers.
// func is a function type. It has one parater and returns pointer to int
typedef int *func(const char);
// funcptr is a pointer to func
func *funcptr;

function prototype return 2D array in C

I am not very good at C and I am really confused about double array. Below is an outline of a code I have a question about. Main function calls CreateRandConn function and passes it a 2D array filled with 0 as an argument. CreateRandConn function takes a 2D array as a parameter, changes some of the value in 2DArray from 0 to 1 and returns the changed 2DArray back to main. I want to indicate in the function prototype the return type of CreateRandConn function is a 2D array. How do I indicate that? I don't really understand the syntax. Is what I wrote wrong? Is the way I am passing the 2DArray as a parameter in the function header incorrect? If so, how I do write it? I still get confused about the relationship between pointers and double arrays. Can someone explain it with the below code outline? Hopefully someone knows what my question is...
//Function prototype
int ** CreateRandConn(char * RandRoom[7], int my2DArray[7][7], char * room_dir);
//Function
int ** CreateRandConn(char * RandRoom[7], int my2DArray[7][7], char * room_dir)
{
...
return my2DArray;
}
int main()
{
int 2DArray[7][7] = {0};
2DArray = CreateRandConn(RandRoomArray, my2DArray[7][7], room_dir);
return 0;
}
I don't really understand the syntax.
Ok, so let's recap the basics:
One cannot assign to an array variable.
If an array gets passed to a function it "decays" to a pointer to its 1st element.
A multidimensional array is just an array of arrays. So a 2D-array is a 1D-array of 1D-arrays, a 3D-array is a 1D-array of 2D-arrays, a 4D-array is a 1D-array of 3D-arrays, and so on ...
A pointer p to an array of N elements of type T is to be defined as: T (*p)[N]
Now for you example:
You have
int 2DArray[7][7] = ...;
for the sake of clarity of the following explanations I change this to be
int a[5][7] = ...;
So this then is passed to a function. Where the following happens/applies:
Following 1. above, it is not possible to pass an array, as if it were possible one would assign it to the variable inside the function, as arrays cannot be assigned, one cannot pass an array.
Following 2. above, the function would need to define the related variable as "a pointer to the arrays 1st element".
Following 3. above, the a's 1st element is an int [7]
Following 4. above, a pointer to an int[7] will be defined as: int(*)[7].
So the function's relevant variable would look like:
... func(int (*pa)[7])
pa points to the 1st element of a. As a side note: From this pointer a the function cannot derive how many elements a actually "provides", will say: how many valid element after the one a points to will follow, so this needs to be passed to the function as well:
... func(int (*pa)[7], size_t rows)
From the steps so far we learned, that an array is not passed, but just a pointer to it's 1st element *1 is passed, is copied into the function's local variable (pa here).
From this directly follows that an array cannot be passed back as the function's return value, but just a pointer to an array's element (typically the 1st)
Looking at how a pointer to an array is defined: T (*p)[N] we know need to derive how a function returning a pointer to an array would look. The function's defalcation somewhat needs to become the p above. So taking T as int and N as 7 we then get:
int (*func(int (*pa)[7], size_t rows))[7];
The trivial implementation and usage then would be:
#include <stdlib.h> /* for size_t */
#define ROWS (5)
#define COLS (7)
int (*func(int (*pa)[COLS], size_t rows))[COLS];
int (*func(int (*pa)[COLS], size_t rows))[COLS]
{
for (size_t i = 0; i < rows; ++i)
{
for (size_t j = 0; j < COLS; ++j)
{
pa[i][j] = 0;
}
}
return pa;
}
int main(void)
{
int a[ROWS][COLS];
int (*pa)[COLS] = func(a, ROWS);
return EXIT_SUCCESS;
}
*1
(which sloppy, but wrongly spoken often is referred to as "a pointer to an array is passed", which in general it is not, but just here, as it's a 2D-array, will say the array's elements are arrays themselves).
If you understood the above, then just for completeness following a less strange looking (but also probably less educational ;-)) version of the above function declaration. It may be declared by using a typedef construct hiding away the somehow complicated declaration of the array-pointers as parameter and return type.
This
typedef int (*PA)[COLS];
defines a type pointing a an array of COLS of ints.
So using PA we can instead of
int (*func(int (*pa)[COLS], size_t rows))[COLS];
write
PA func(PA pa, size_t rows))[COLS];
This version is identical to the above.
And yes it looks simpler, but brings along the fact, that pointers pa and the function's return value) are not identifiable as being pointers by just looking at their definition. Such constructs are considered "bad practice" by many fellow programmers.

What does an empty parameter list mean? [duplicate]

This question already has answers here:
Why does a function with no parameters (compared to the actual function definition) compile?
(11 answers)
Closed 9 years ago.
The book that i am currently reading states that when you declare a function in c that accepts no arguments, but you do not use the keyword void "the function call can pass any
arguments it wants". so i attempted this.
int number();
int main(void)
{
int x =1;
printf("%d",number(x));
}
int number()
{
return x;
}
but it did not compile??? how does this work?
This is an obsolescent feature1 from before C was standardized, decades ago.
Never use it.
In ancient C, a decade before you were born, you could declare a function with no parameters. When you called it, the compiler would promote the arguments to default types and pass them to the function. Essentially, the compiler figured out the parameter declarations from the arguments in the call.
The function should still be defined with parameters, and they should match the way the function is called.
1 “Feature” is the wrong word. It was the way things were done at the time, since better ways were not yet widely developed. In a new programming language, this characteristic would be considered a deficiency.
In support of Eric Postpischil's answer I would like to quote from the C11 standard (6.11 Future language directions)
6.11.6 Function declarators
The use of function declarators with empty parentheses (not
prototype-format parameter type declarators) is an obsolescent
feature.
and
6.11.7 Function definitions
The use of function definitions with separate parameter identifier and
declaration lists (not prototype-format parameter type and identifier
declarators) is an obsolescent feature.
Emphasis is mine :)
The issue here is that your function number has no knowledge of x.
That is, when you have the function number return x, it doesn't have any x in scope to return, and so this is a compile error. If, instead, you wrote:
int number() {
return 5;
}
it would compile fine.
Well, if you want pass something to it without limit , you may need a a variable argument list.Here is an example:
#include <stdio.h>
#include <stdarg.h>
int number(int , ... );
int main(void)
{
int x =1;
printf("%d",number(1,x));
}
int number(int n, ... )
{
va_list ap;
va_start(ap,n);
int x = va_arg(ap,int);
va_end(ap);
return x;
}
Or , if you just want to pass x but not use it.
#include <stdio.h>
int number();
int main(void)
{
int x =1;
printf("%d",number(x));
}
int number()
{
int x = 1;
return x;
}
It can compile and work. When you declare int number (); in C , you mean this function can be given unspecial type . however , you can't use it.
Well I edited the whole answer after finding the answer.
What you want to do is number(void) not main(void). That's what you wanted and that will print any variable as a integer. If you pass the char "F" int number(void) will return the number 70, the int form of "F". In code:
int number(void e);
void main(){
char C = 'F';
printf("%d",number(C));
};
int number(void e){
return e;
};
Note:
You must always pass an argument if you want a variable that's out of scope.

Static hint in variable length arrays

I'm a bit confused at the difference here, in C99:
int myfunc (int array[n], int n) { ... }
will not compile. As far as I know you must always put the reference to the array size first, so it has to be written:
int myfunc (int n, int array[n]) { ... }
But if you supply the static keyword, this works absolutely fine:
int myfunc (int array[static 1], int n) { ... }
This order if far preferable to me, as I'm used to having arrays come first in a function call, but why is this possible?
Edit: Realising that the third example isn't actually a VLA helps...
For reference, this was the piece of code I was looking at that led to the question:
int sum_array(int n, int m, int a[n][m])
{
int i, j, sum = 0;
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
sum += a[i][j];
return sum;
}
The reason why
int myfunc (int n, int array[n]) { ... }
is valid and
int myfunc (int array[n], int n) { ... }
is not is due to the lexical scoping rules of C. An identifier cannot be used before it has been introduced in the scope. There are a few exceptions to this rule but this one is not one of them.
EDIT: here is the relevant paragraph of the C Standard:
(C99, 6.2.1p7) "Any other identifier has scope that begins just after the completion of its declarator."
This rule also applies to parameters declaration at function prototype scope.
The reason for error has already been explained to you: you have to declare n before you can use it in other declarations.
However, it is worth noting that none of these declarations actually declare variable length arrays, as you seem to believe.
It is true that syntax with [n] was first allowed in C99 and that it is formally a VLA declaration, but nevertheless in the given context all of these declarations declare array as a parameter of int * type, just like it has always been in C89/90. The [n] part is not a hint of any kind. The fact that you can use [n] in this declaration is indeed a side-effect of VLA support, but this is where any relationship with VLA ends. That [n] is simply ignored.
A "hint" declaration requires keyword static inside the []. So, your declaration with [static 1] is equivalent to classic int array[1] declaration (meaning that 1 is ignored and the parameter has type int *) except that it gives the compiler a hint that at least 1 element must exist at the memory location pointed by array.
It's because arrays must be declared with a constant value so you cannot create an array using a variable size and therefore cannot pass an array with a variable size. Also if it is just a single-dimension array you don't need to pass a value in at all, that is the point of passing in the second parameter to tell you the length of your array.
To get this to work properly just write the function header like this:
int myfunc (int myArray[], int n) {...}
The order shouldn't matter, but you cannot have the size of an array you are passing be variable it must be a constant value.
If you are using GCC and are willing to use some of their extensions, you can accomplish what you wish right here:
int myFunc (int len; /* notice the semicolon!! */ int data[len], int len)
{
}
The documentation for this extension (Variable Length Arrays) is here.
Please note that this extension is NOT available in clang for some reason, I'm not quite sure why, though.
EDIT: Derp, scope, of course.
My question is; why do you need to do it at all? You're really getting a pointer anyway (you can't pass arrays to a function in C, they degrade to a pointer, regardless of the function's signature). It helps to let the caller know the expected size of the input, but beyond that it is useless. Since they are already passing the size, just use...
int myfunc(int arr[], size_t size) {
// ...
}
Or
int myfunc(int *arr, size_t size) {
// ...
}

array of pointers to functions

i need to write a function that receives an array of pointers to functions.
i wrote the following code, however i'm having trouble in testing it at the moment.
is this the correct way to define a pointers to function array?
typedef (*Function)(double);
void func(Function* arr);
and if i want to declare the size of the array with [20] do i write:
void func(Function arr[20]);
?
thanks for your help
First, my usual method for figuring out complex types. Start with the identifier, and then add on the rest one step at a time:
f -- f
f[N] -- is an N-element array
*f[N] -- of pointers
(*f[N])() -- to functions
T (*f[N])() -- returning T
For an array of pointers to functions taking a double parameter and returning a double value, that would be
double (*f[N])(double);
However, remember that expressions of array type "decay" from type "N-element array of T" to "pointer to T" in most contexts. When you pass an array expression as an argument to a function, what the function actually receives is a pointer. So, instead of receiving an object of type "N-element array of pointer to function returning double", your function will receive an object of type "pointer to pointer to function returning double", or
double (**f)(double)
So your function definition would look something like
void func(double (**f)(double))
{
int i;
...
for (i = 0; f[i] != NULL; i++)
{
double x = (*f[i])((double) i);
}
}
And the caller would look something like
double a(double x) {...}
double b(double x) {...}
double c(double x) {...}
void foo(void)
{
double (*list[])(double) = {a, b, c, NULL};
func(list);
}
If you want to use typedefs instead, you could use something like this:
typedef double Dblfunc(double); // typedef for function type
typedef Dblfunc *Dblfuncptr; // typedef for function pointer type
void func(Dblfuncptr *f)
{
int i;
for (i = 0; f[i] != NULL; i++)
{
double x = (*f[i])((double) i);
...
}
}
...
void foo(void)
{
Dblfuncptr list[] = {a, b, c, NULL}; // EDIT: fixed type
func(list);
}
Using the typedefs makes the array and function parameter look more like regular types. Personally, I prefer using the "raw" types, since it shows explicitly that I'm dealing with pointers to functions, and it shows what the return and parameter types are.
If you correct the typedef to include a return type typedef void (*Function)(double);, that array declaration will work fine. You'd call it by calling (arr[index])(3.14) for the array case.
BTW: http://www.newty.de/fpt/fpt.html is a handy reference for function pointers.
What does the function return? You're the return type in the function pointer typedef, like you should have something like
typedef double (*Function)(double);
it looks almost correct i think you forgot the return type when declaring Function:
typedef int (*Function)(double)
instead
the second declaration is invalid too i think because it is invalid to specify array size for function parameters
void func (Function*)
will do just fine

Resources