C Header file error: expected identifier or ‘(’ before ‘[’ token - c

I'm a complete c newb. I'm trying to define a few functions in a header file and then implement them in a separate file. But when I try running gcc runtime.c I get the following error:
In file included from runtime.c:1:
runtime.h:7: error: expected identifier or ‘(’ before ‘[’ token
Here's the contents of runtime.h:
#ifndef HEADER
#define HEADER
/*given two arrays of ints, add them
*/
int[] * _addInts(int[] *x, int[] *y);
#endif
What's the error? I tried browsing header files but they started adding things like "extern" and "intern" and crazy ifdef's. Thanks for your help, Kevin

You should just pass pointers (since if you pass arrays to a function, what;'s really passed is a pointer anyway). Also, you can't return an array - again, just return a pointer:
int* _addInts(int *x, int *y); // equivalent to: int* _addInts(int x[], int y[]);
You'll also have to arrange for the number of elements to be passed in somehow. Something like the following might work for you:
int* _addInts(int *x, int *y, size_t count);
Also - do not fall into the trap of trying to use sizeof on array parameters, since they're really pointers in C:
int* _addInts(int x[], int y[])
{
// the following will always print the size of a pointer (probably
// 4 or 8):
printf( "sizeof x: %u, sizeof y: %u\n", sizeof(x), sizeof(y));
}
That's one reason why I'd prefer having the parameters be declared as pointers rather than arrays - because they really will be pointers.
See Is there a standard function in C that would return the length of an array? for a macro that will return the number of elements in an array for actual arrays and will cause a compiler error (on most compilers) much of the time when you try to use it on pointers.
If your compiler is GCC, you can use Linux's trick: Equivalents to MSVC's _countof in other compilers?

Get rid of each "[]"
As an array is a pointer, you only need to pass the pointers, like so:
int* _addInts(int* x, int* y);
EDIT: Also pass the size.

Use:
int* addInts(int* x, int* y, int size);

You have the [] in the wrong locations. The syntax for declaring arrays in "C" has the [] coming after the item you want to be an array, not between the type declaration and the item (like Java and C# use). I am not sure what you are trying to declare, but here are some options:
If you are trying to declare that you will be using a function named "_addInts()" that returns a pointer to an int, and takes as its parameters two separate arrays of pointers to integers named x and y --
int * _addInts(int *x[], int *y[]);
If you want to declare a function that returns an array of integer pointers:
int * _addInts(int *x[], int *y[])[];
If _addInts is a function that takes two arrays of int (as opposed to arrays of int *):
int * _addInts(int x[], int y[]);
Note that the following are (nearly) equivalent, and can be used interchangeably in declarations such as you are attempting.
int *x
and
int x[]
as are:
int **x
and
int *x[]

Related

how to pass a condition as parameter to function in C?

I have created an array of function pointers to swap two variables.
pointer pointing to these functions namely: swap1, swap2. swap3 and swap4.
swap2 is swaping using pointer passed as arguments.
but while declaring the function pointer, only int and int are passed as arguments. after compiling this causes many warnings.
so do we have a better way of passing the argument, where we put condition in function call itself.
code is given below.
#include <stdio.h>
int swap1(int ,int );
int swap2(int* ,int* );
int swap3(int ,int );
int swap4(int, int);
int swap1(int a,int b)
{
int temp=a;
a=b;
b=temp;
printf("swapped with 3rd variable :%d, %d\n", a,b);
}
int swap2(int *a,int *b)
{
int temp = *a;
*a = *b;
*b = temp;
printf("swapped with pointer :%d, %d\n", *a,*b);
}
int swap3(int a,int b)
{
a+=b;
b=a-b;
a-=b;
printf("swapped with 2 variable :%d, %d\n", a,b);
}
int swap4(int a,int b)
{
a=a^b;
b=a^b;
a=a^b;
printf("swapped with bitwise operation :%d, %d\n", a,b);
}
int main()
{
int ch;
int a=3;
int b=4;
printf("enter the option from 0 to 3\n");
scanf("%d",&ch);
int (*swap[4])(int, int) ={swap1,swap2,swap3,swap4};// function pointer
/*can we pass something like int(*swap[4]( condition statement for 'pointer to variable' or 'variable')*/
if (ch==1)// at '1' location, swap2 is called.
{
(*swap[ch])(&a,&b);//passing the addresses
}
else
{
(*swap[ch])(a,b);
}
return 0;
}
some warnings are as follows.
at line 36 in file '9e748221\script.c'
WARNING: found pointer to int where int is expected
at line 47 in file '9e748221\script.c'
WARNING: found pointer to int where int is expected
at line 47 in file '9e748221\script.c'
Well yes. There are a number of problems with your code, but I'll focus on the ones to which the warnings you presented pertain. You declare swap as an array of four pointers to functions that accept two int arguments and return an int:
int (*swap[4])(int, int)
Your function swap2() is not such a function, so a pointer to it is not of the correct type to be a member of the array. Your compiler might do you a better favor by rejecting the code altogether instead of merely emitting warnings.
Having entered a pointer to swap2() into the array anyway, over the compiler's warnings, how do you suppose the program could call that function correctly via the pointer? The type of the pointer requires function arguments to be ints; your compiler again performs the dubious service of accepting your code with only warnings instead of rejecting it.
Since the arguments in fact provided are the correct type, it might actually work on systems and under conditions where the representations of int and int * are compatible. That is no excuse, however, for writing such code.
Because pointers and ints are unchanged by the default argument promotions, one alternative would be to omit the prototype from your array declaration:
int (*swap[4])() = {swap1,swap2,swap3,swap4};
That says that each pointer points to a function that returns int and accepts a fixed but unspecified number of arguments of unspecified types. At the point of the call, the actual arguments will be subject to the default argument promotions, but that is not a problem in this case. This option does prevent the compiler from performing type checking on the arguments, but in fact you cannot do this correctly otherwise.
Your compiler might still warn about this, or could be induced to warn about it with the right options, but the resulting code nevertheless conforms and does the right thing, in the sense that it calls the pointed-to functions with the correct arguments.
To deal with the warnings first: You declare an array of functions which take int parameters. This means that swap2 is incompatible with the type of element for the array you put it in. This will generate a diagnostic.
Furthermore, when you call one of the functions in the array, the same array declaration tells the compiler that the parameters need to be ints not pointers to int. You get two diagnostics here, one for each parameter.
To fix the above all your functions need to have compatible prototypes with the element type of the array. Should it be int or int*? This brings us to the other problem.
C function arguments are always pass by value. This means that the argument is copied from the variable onto the stack (or into the argument register depending on the calling convention and argument count - for the rest of this post, I'll assume arguments are placed on the stack for simplicity's sake). If it's a literal, the literal value is put on the stack. If the values on the stack are changed by the callee no attempt is made by the caller, after the function returns, to put the new values back in the variables. The arguments are simply thrown away.
Therefore, in C, if you want to do the equivalent of call by reference, you need to pass pointers to the variables you use as arguments as per swap2. All your functions and the array should therefore use int*. Obviously, that makes one of swap1 and swap2 redundant.
The correct array definition is
int (*swap[4])(int*, int*) = {swap1, swap2, swap3, swap4};
and the definition of each function should be modified to take int* parameters. I'd resist the temptation to use int (*swap[4])() simply because it circumvents type safety. You could easily forget the & in front of an int argument when the called function is expecting a pointer which could be disastrous - the best case scenario when you do that is a seg fault.
The others have done great work explaining what the problems are. You should definitely read them first.
I wanted to actually show you a working solution for that sort of problem.
Consider the following (working) simple program :
// main.c
#include <stdio.h>
void swap1(int* aPtr, int* bPtr) {
printf("swap1 has been called.\n");
int tmp = *aPtr;
*aPtr = *bPtr;
*bPtr = tmp;
}
void swap2(int* aPtr, int* bPtr) {
printf("swap2 has been called.\n");
*aPtr += *bPtr;
*bPtr = *aPtr - *bPtr;
*aPtr -= *bPtr;
}
int main() {
int a = 1, b = 2;
printf("a is now %d, and b is %d\n\n", a, b);
// Declare and set the function table
void (*swapTbl[2])(int*, int*) = {&swap1, &swap2};
// Ask for a choice
int choice;
printf("Which swap algorithm to use? (specify '1' or '2')\n>>> ");
scanf("%d", &choice);
printf("\n");
// Swap a and b using the right function
swapTbl[choice - 1](&a, &b);
// Print the values of a and b
printf("a is now %d, and b is %d\n\n", a, b);
return 0;
}
First of, if we try to compile and execute it:
$ gcc main.c && ./a.out
a is now 1, and b is 2
Which swap algorithm to use? (specify '1' or '2')
>>> 2
swap2 has been called.
a is now 2, and b is 1
As myself and others mentioned in answers and in the comments, your functions should all have the same prototype. That means, they must take the same arguments and return the same type. I assumed you actually wanted to make a and b change, so I opted for int*, int* arguments. See #JeremyP 's answer for an explanation of why.

Access a 2D array[x][y] as a 1D array[z] in C

I recently started writing chunks of C code as part of my university's programming lessons (so you can freely assume that I am a complete idiot). I'm trying to write a function that writes a 2D array's data to a file, but I'm having difficulties. I declare the array in main, I have its x and y dimensions saved as #defines, and I want to call my function() like so;
include "function.h"
#define /* x_res, y_res */
int main(){
static unsigned char pic[x_res][y_res];
/* do some operations on pic*/
function(pic,x_res,y_res);
}
The function itself is saved in a header file and is intended to be included at the very top of my main .c file. It goes something like this;
void function(unsigned char arry,int x_res,int y_res){
/* some calculations, declaring file pointer with fopen() */
for(int i=0;i<y_res;i++){
for(int j=0;j<x_res;j++){
fprintf(f,"%c",arry[i][j]);
}
}
}
I'm greeted with an error in the line fprintf(f,"%c",arry[i][j]); saying that the "subscripted value is neither array nor pointer nor vector", which is false since I know that arry is an array. Furthermore, if I try to replace said line with something like fprintf(f,"%c",arry[i*j+j]);, the error goes away, but the file output is gibberish (I'm assuming I'm only printing the addresses of the first-dimension elements of arry).
The question, then; Why can't 2D arrays be accessed like their 1D counterparts, and how do I work around this? I would imagine that an int array[][]={{0,1},{2,3}}; would give an output of
array[0] -> 0
array[1] -> 1
array[2] -> 2
array[3] -> 3
, but this is not the case -- it prints 0, 2, and then two memory addresses.
I've tried declaring my function to accept arguments as void function(unsigned char arry[*value of x_res*][*value of y_res*],x_res,y_res), which works but is not how I would like the function to work.
I've looked at some other online examples but it seems few people have had a similar problem. I tried some answers from this question but again things do not work. For example, using void function(unsigned char **arry,x_res,y_res) works with accessing the array as 2D (arry[i][j]), but again, like with the example above, most values (all that aren't in the first column) are trash.
In C99 and later, it is possible to have a VLA
void function(int x_res, int y_res, int char[][y_res])
{
for(int i=0;i<x_res;i++)
{
for(int j=0;j<y_res;j++)
{
fprintf(f,"%c",arry[i][j]);
}
}
}
The problem is that support of an implementation for VLAs was made optional in C11 (i.e. a C11 compiler is not required to support them). And VLAs are definitely not supported in C90 (the ISO C standard of 1990).
An declared array is contiguous in memory, so can be treated like a flat 1D array. For example;
void function2(int x_res, int y_res, unsigned char *arr)
{
for(int i=0;i<x_res;i++)
{
for(int j=0;j<y_res;j++)
{
fprintf(f,"%c",arr[i*y_res + j]);
}
}
}
int main()
{
unsigned char x[10][20];
unsigned char y[10*20];
unsigned char *z = malloc(10*20*sizeof(*z));
/* initialise elements x, y, and z */
function2(10,20, (unsigned char *)x);
function2(10,20, &x[0][0]);
function2(10,20, y);
function2(10,20, z);
}
The type conversion in the first call of function() is needed since a 2D array of unsigned char cannot be implicitly converted to a unsigned char *. However, the address of x and the address of x[0][0] have the same value, even though they have different types.
A gotcha with this technique is that the dimensions passed (first two arguments of function2()) are not checked at compile time. For example;
int xx[5][6];
function2(10, 20, (unsigned char *)xx); /* danger, Will Robinson!! */
function2(10, 20, &xx[0][0]); /* danger, danger!! */
will compile but, since the dimensions of xx are less than the first two arguments tell function2() to expect, will cause function2() to have undefined behaviour for both calls.

What does "[*]" (star modifier) mean in C? [duplicate]

This question already has answers here:
Why use an asterisk "[*]" instead of an integer for a VLA array parameter of a function?
(2 answers)
Closed 6 years ago.
While trying to implement a C11 parser (for educational purposes), I found that in C11 (p. 470) but also in C99 (p. 412) (thanks Johannes!), the direct declarator is defined as:
(6.7.6) direct-declarator:
direct-declarator [ type-qualifier-list? * ]
At first, I thought this was an error in the grammar (the type list shouldn't be optional). However, when I tried this out in my reference compiler (clang), I got an rather unexpected error:
int array[*] = { 1, 2, 3 };
// error: star modifier used outside of function prototype
So apparently, (in clang) this is called the star modifier.
I quickly learned that they can only be used in function signatures:
void foobar(int array[*])
However, they can only be used in the declaration. Trying to use it in a function definition results in an error as well:
void foobar(int array[*]) {
// variable length array must be bound in function definition
}
So as far as I can tell, the intended behaviour is to use [*] in the function declaration and then use a fixed number in the function definition.
// public header
void foobar(int array[*]);
// private implementation
void foobar(int array[5]) {
}
However, I have never seen it and I don't quite understand the purpose of it either.
What is its purpose, why was it added?
What's the difference with int[]?
What's the difference with int *?
What is its purpose, why was it added?
Purpose is seen when a variable length two dimentional array is used as a function parameter. The function
int foo(int n, int m, int a[n][m]) {...}
can be prototyped as any of the following
int foo(int , int, int [][*]);
int foo(int , int, int a[*][*]);
int foo(int , int, int (*a)[*]);
int foo(int n, int, int a[n][*]);
int foo(int , int m, int a[*][m]);
int foo(int , int m, int (*a)[m]);
int foo(int n, int m, int a[n][m]);
In case of two dimensional array, when used as function parameter, size of the second dimension can't be omitted. If the name of first variables in function prototype is omitted then it wouldn't be possible to specify the length (second dimension) of the array. The * gives the clue that the length of the array will be determined by the second parameter.
What's the difference with int[]?
What's the difference with int *?
In case of 1D array, for the function definition
int bar(int n, int a[n]} {...}
any of the following prototype is valid
int bar (int , int *);
int bar (int , int [*]);
int bar (int , int []);
int bar (int n, int a[]);
int bar (int n, int a[n]);
int bar (int n, int [n]);
In this case neither * nor n is necessary as compiler will treat both of int [*] and int [n] as int *. So, with one dimensional array you can't see much difference.
NOTE: When using variable length array as a function parameter, order of parameter is important. Order of parameters for first four prototypes of bar can be switched, but in latter two first parameter must not be the array itself.
int bar (int a[n], int n); //Wrong. Compiler has not yet seen 'n'.
The C rationale document for C99 says
A function prototype can have parameters that have variable length array types (§6.7.5.2) using a special syntax as in
int minimum(int, int [*][*]);
This is consistent with other C prototypes where the name of the parameter need not be specified.
What's the difference with int[]
What's the difference with int *.
I think it's simply that those types in a function prototype means "pointer", while a [*] in a non-top position (int[*] still equals int[] I think, in a function prototype) actually is valid and means array
// not recommended though: it is now unclear what the parameters
// mean to human callers!
void f(int, int [][*]);
void f(int n, int x[][n]) {
x[1][0] = 1;
}
int main() {
int a[2][1];
f(1, a);
printf("%d\n", a[1][0]);
}
As for the purpose, when indexing the array in the function definition, the compiler needs to know how many integers of the next index to skip when giving the first index (x[i] skips i * n integers in f above). But this information is not needed in the non-defining prototype declaration, hence it can be left out and replaced by *.

Function parameter as array with declared size

I frequently use the following convention to inform client code that a function requires an argument of an array with defined size:
/* File foo.h */
int foo (int arg[10]);
The message I want to give to client code is that they must provide an array of type int with 10 positions.
I am aware that it is not very usual, so I came here to ask: Am I missing any side effect of this convention ? Is it anyhow harmful?
Thank!
If you want to insist on getting an array of size 10, you can use:
int foo (int (*arg)[10]);
The ill-side effects of this are:
In the function, you have to use:
(*arg)[index]
instead of just
arg[index]
The calling function must use:
int array[10];
foo(&array);
instead of
int array[10];
foo(array);
You cannot use an array that has more than 10 elements.
int array[20];
foo(&array); // Not OK.
You cannot use a malloced array.
int* array = malloc(sizeof(int)*10);
foo(array); // Not OK.
Now pick the solution that is least harmful.
struct arrayContainerTen{
int data[10];
}
void aFunction(struct arrayContainerTen *pAnArray)
{
size_t size = sizeof(pAnArray->data);
}
main()
{
arrayContainerTen anArray;
aFunction(&anArray);
}
There's no harm in writing it like this. But just be aware that the compiler will not enforce the requirement. A declaration like that is treated by the compiler as if you'd written.
int foo(int *arg);

Why does C disallow an array return type?

Why is this valid in C
int * foo(int a,int b){
...
}
but this is invalid
int [] foo(int a,int b){
...
}
The syntax is somewhat funny.
int foo(int a, int b) []
{
...
}
But it's not allowed anyway. See n1256 6.7.5.3 paragraph 1, "Function declarators".
A function declarator shall not specify a return type that is a function type or an array type.
You can return pointers to arrays:
int (*foo(int a, int b)) []; // Weird syntax, n'est-ce pas?
But you might as well just return a pointer instead, since the following are equivalent:
int array[] = { ... };
int *x = array, (*y)[] = &array;
x[0];
(*y)[0]; // same as above, just with more cumbersome syntax
Typically, if a function needs to return an array of int, you either return the pointer or pass the pointer in. One of the following:
int *func(int a, int b); // Allocated by func
void func(int a, int b, int *array); // Allocated by caller
void func(int a, int b, int **array); // Allocated by func
The "struct-hack" also works for arrays that have a fixed size:
struct { int arr[50]; } array_struct;
struct array_struct func(int a, int b);
But this is not recommended unless the array is small.
Rationale:
Arrays are often large, and often have a size not known until runtime. Since parameters and return values are passed using the stack and registers (on all ABIs I know of), and the stack has a fixed size, it is somewhat dangerous to pass such a large object around on the stack. Some ABIs also don't gracefully handle large return values, potentially causing extra copies of return values to be generated.
The following code can also be dangerous:
void func(...)
{
int arr[BIG_NUMBER]; // potential for stack overflow
int *ptr = alloca(sizeof(int) * BIG_NUMBER); // potential for stack overflow
}
In C passing arrays by value is not directly supported (even when you write int [] as a parameter is actually interpreted as int *), if I remember correctly it's some sort of artifact of the passage from BCPL to C.
That being said, you can actually return arrays encapsulating them into structs:
struct
{
int value[20]
} foo(int a, int b)
{
/* ... */
}
(this trick obviously works also for parameters)
First, recall that arrays in C are really just syntactic sugar around pointers to blocks of memory. So C isn't restricting the functionality of the language by forcing the use of the former notation (See the example which follows).
Also, they may have made this choice to prevent early programmers from writing code like this:
char *itoa(int n){
char retbuf[25];
sprintf(retbuf, "%d", n);
return retbuf;
}
ref
Which looks simple enough, but what happens to the memory retbuf points to at the end of the function? Can the calling functions trust the data in the pointer it gets back?

Resources