c macro, array definition as parameter - c

I have this method
foo_l(int *array, size_t l)
{
/*
code
*/
}
and I wrote this macro
#define foo(X) foo_l(X,sizeof(X)/sizeof(int))
So I can use them as follows
int main()
{
int a[]={1,2,3};
foo(a);
return 0;
}
and avoid writing the length of the array every time.
My question is, can I extend my macro so it can handle something like
foo_l((int[]){1,2,3}, 3);
with an array declared in the function parameter field?
Because foo((int[]){1,2,3}) doesn't work! I think that the problem is that the macro see (int[]){1,2,3} as a list of parameters and not as a unique parameter. Any Idea?
P.S. I'm pretty new to the macro world and I usually use c99.

When being passed to the preprocessor, the macro foo((int[]){1,2,3}) fails because the preprocessor believes it provided 3 parameters instead of 1:
foo((int[]){1,2,3});
// is believed to be:
// Start of macro: foo(
// Parameter 1: (int[]){1,
// Parameter 2: 2,
// Parameter 3: 3}
// End of macro: );
So it doesn't compile and gives something like:
a.c: In function ‘main’:
a.c:15:23: error: macro "foo" passed 3 arguments, but takes just 1
foo((int[]){1,2,3});
Adding another pair of parenthesis solves the problem:
// This shall work
foo(((int[]){1,2,3}));
EDITED:
Yes I guess this may not be a good design, since people like average programmers may be very likely to pass a pointer instead of an array type to your macro foo, and it would fail as #DwayneTowell points out.
Please be careful about this.
:)

What you have suggested is not a good idea, because it will fail in cases like the following:
int a[] = {1,2,3,4};
int *b = a;
foo(b); // becomes foo_l(b,sizeof(b)/(sizeof(int));
// probably becomes foo_l(b,1)
In general the size parameter will be wrong if the first parameter is a pointer to an array instead of the array itself. Usually the expression will evaluate to 1, when sizeof(int *)==sizeof(int), which is very common but required by the standard.

Related

How to wrap function with prefix and suffix in C

I'd like to know how to solve the wrapper problem from the
Stroustrup paper but in C. I'm trying to find an efficient way to call
// prefix
GenericFunctionCallThatCouldHaveAnyNumberOfArgs();
// suffix
I've thought about creating a proxy function that takes an input a function pointer but the functions I want to wrap do not all have the same function signature.
My current solution is to create a Macro:
#define CALL(func) prefix; func; suffix;
CALL(myfunction(a, 'b', 1))
It works but it makes the code harder to understand especially when the prefix and suffix are complicated. Also the prefix and suffix are not necessarily calls to functions, they can be enclosures too. Is there a design pattern in C that does this efficiently (in terms of lines of code) while still maintaining readability.
I've thought about creating a proxy function that takes an input a function pointer but the functions I want to wrap do not all have the same function signature.
This can be solved by adding another layer of indirection. It won't make the code any shorter, though.
Let's say we want to call two functions, foo() (passing no arguments) and bar(42, "hello") (two arguments of different types) with the same prefix/suffix code.
We can do it like this:
void call_decorated(void (*f)(void *), void *p) {
printf("prefix code\n");
f(p);
printf("suffix code\n");
}
This lets us call any function that takes a single void * argument. To use this with foo and bar, we have to write adapter functions:
void wrap_foo(void *p) {
foo();
}
struct bar_args {
int n;
const char *s;
};
void wrap_bar(void *p) {
struct bar_args *args = p;
bar(args->n, args->s);
}
Now we can call call_decorated like this:
call_decorated(wrap_foo, NULL);
struct bar_args args = { 42, "hello" };
call_decorated(wrap_bar, &args);
This gets very tedious, but there is only one instance of the prefix/suffix code in the source.
For function calls of return type void you could use the comma operator, which - with some restrictions - allows to specify several expressions that are evaluated one after the other, including a function call.
For example, you could write
#define prefix printf("something in prefix\n")
#define suffix printf("something as suffix\n")
void someFunction(int x) {
printf("some function, parameter value %d\n", x);
}
#define CALL(func) (prefix,func,suffix)
int main() {
CALL(someFunction(10));
}
Output:
something in prefix
some function, parameter value 10
something as suffix
There are several restrictions on what can be an expression used within a comma operator. For example, you cannot define a variable in the course of such an expression. However, there are some strategies to overcome this, e.g. by introducing global variables or by calling functions (which may define local variables, of course).
The reason for return type void is that you want to call your function "in the middle", i.e. not as the last expression in the comma operator, but the result of the comma operator per is always the value to which the last expression evaluates. Note further that with the #define CALL(func)- approach any change in the prefix or in the suffix requires recompilation of your program. But I think you are aware of this anyway.
Hope it helps.

Resource Acquisition Is Initialization in C lang

The question is: Could you please help me understand better the RAII macro in C language(not c++) using only the resources i supply at the bottom of this question? I am trying to analyse it in my mind so as to understand what it says and how it makes sense(it does not make sense in my mind). The syntax is hard. The focus of the question is: i have trouble reading and understanding the weird syntax and its implementation in C language.
For instance i can easily read, understand and analyse(it makes sense to me) the following swap macro:
#define myswap(type,A,B) {type _z; _z = (A); (A) = (B); (B) = _z;}
(the following passage is lifted from the book: Understanding C pointers)
In C language the GNU compiler provides a nonstandard extension to
support RAII.
The GNU extension uses a macro called RAII_VARIABLE. It declares a
variable and associates with the variable:
A type
A function to execute when the variable is created
A function to execute when the variable goes out of scope
The macro is shown below:
#define RAII_VARIABLE(vartype,varname,initval,dtor) \
void _dtor_ ## varname (vartype * v) { dtor(*v); } \
vartype varname __attribute__((cleanup(_dtor_ ## varname))) = (initval)
Example:
void raiiExample() {
RAII_VARIABLE(char*, name, (char*)malloc(32), free);
strcpy(name,"RAII Example");
printf("%s\n",name);
}
int main(void){
raiiExample();
}
When this function is executed, the string “RAII_Example” will be displayed. Similar results can be achieved without using the GNU extension.
Of course you can achieve anything without using RAII. RAII use case it to not have to think about releasing ressources explicitly. A pattern like:
void f() {
char *v = malloc(...);
// use v
free v;
}
need you to take care about releasing memory, if not you would have a memory leak. As it is not always easy to release ressources correctly, RAII provides you a way automatize the freeing:
void f() {
RAII_VARIABLE(char*, v, malloc(...), free);
// use v
}
What is interesting is that ressource will be released whatever the path of execution will be. So if your code is a kind of spaghetti code, full of complex conditions and tests, etc, RAII lets you free your mind about releasing...
Ok, let's look at the parts of the macro line by line
#define RAII_VARIABLE(vartype,varname,initval,dtor) \
This first line is, of course, the macro name plus its argument list. Nothing unexpected here, we seem to pass a type, a token name, some expression to init a variable, and some destructor that will hopefully get called in the end. So far, so easy.
void _dtor_ ## varname (vartype * v) { dtor(*v); } \
The second line declares a function. It takes the provided token varname and prepends it with the prefix _dtor_ (the ## operator instructs the preprocessor to fuse the two tokens together into a single token). This function takes a pointer to vartype as an argument, and calls the provided destructor with that argument.
This syntax may be unexpected here (like the use of the ## operator, or the fact that it relies on the ability to declare nested functions), but it's no real magic yet. The magic appears on the third line:
vartype varname __attribute__((cleanup(_dtor_ ## varname))) = (initval)
Here the variable is declared, without the __attribute__() this looks pretty straight-forward: vartype varname = (initvar). The magic is the __attribute__((cleanup(_dtor_ ## varname))) directive. It instructs the compiler to ensure that the provided function is called when the variable falls out of scope.
The __attribute__() syntax is is a language extension provided by the compiler, so you are deep into implementation defined behavior here. You cannot rely on other compilers providing the same __attribute__((cleanup())). Many may provide it, but none has to. Some older compilers may not even know the __attribute__() syntax at all, in which case the standard procedure is to #define __attribute__() empty, stripping all __attribute__() declarations from the code. You don't want that to happen with RAII variables. So, if you rely on an __attribute__(), know that you've lost the ability to compile with any standard conforming compiler.
The syntax is little bit tricky, because __attribute__ ((cleanup)) expects to pass a function that takes pointer to variable. From GCC documentation (emphasis mine):
The function must take one parameter, a pointer to a type compatible
with the variable. The return value of the function (if any) is
ignored.
Consider following incorrect example:
char *name __attribute__((cleanup(free))) = malloc(32);
It would be much simpler to implement it like that, however in this case free function implicitely takes pointer to name, where its type is char **. You need some way to force passing the proper object, which is the very idea of the RAII_VARIABLE function-like macro.
The simplified and non-generic incarnation of the RAII_VARIABLE would be to define function, say raii_free:
#include <stdlib.h>
void raii_free(char **var) { free(*var); }
int main(void)
{
char *name __attribute__((cleanup(raii_free))) = malloc(32);
return 0;
}

Implicit declaration of function is invalid in C99

I am new to C language and I am having a problem that I really don't understand. I am trying to get an array from another function but when I try to extract the information, it gives me the following warning:
Implicit declaration of function 'getk_vector_calculation' is invalid in C99
Array initializer must be an initializer list or string literal
Here is the code:
int k_vector_calculation(int krec[3])
{
...
krec [0] = l*u[0]+m*v[0]+o*[0] ;
krec [1] = l*u[1]+m*v[1]+o*[1] ;
krec [2] = l*u[2]+m*v[2]+o*[2] ;
return k_vector_calculation( &krec[3] )
}
int main ()
{
char krec[3] = getk_vector_calculation(&krec[3]);
...
}
in your main() the function you called is getk_vector_calculation() [which is not k_vector_calculation()] and which is not declared or defined before the usage.
To resolve this,
either #include the header file containg the declaration of getk_vector_calculation() in your sorce file. [Considering getk_vector_calculation() is in some other file]
or, add a forward declaration of getk_vector_calculation() before main() and define getk_vector_calculation() somewhere.
To know more about implicit declaration, you can check this question.
EDIT:
As others have pointed out, there are many more problems in your code snippet. But since the question title is limited to implicit declaration error, IMO, this answer should do the needful. The remaining error(s) is(are) altogether a different aspect.
In older versions of C, functions that had not been declared yet were still able to be called, and it was assumed that they returned int and took an unspecified number of arguments. Strictly speaking, in C99, it is not permitted to call a function without declaring it first.
In your case however, you are trying to call a function called getk_vector_calculation but you have defined a function called k_vector_calculation (no get at the beginning).
You are also trying to initialise an array using a function, which is not permitted (in C, functions cannot return arrays). Simply declare the array and call k_vector_calculation as a separate statement, e.g.:
int krec[3] = {0};
k_vector_calculation(krec);
Don't use &krec[3] as this points to an invalid location. Use &krec[0] to provide the address of the first element in the array, or equivalently just krec will do. N.b. also that you declare an array of type char, but your function accepts a pointer to int, and these types are not compatible. Your function also calls itself unconditionally so there is a guaranteed infinite recursion if the snipped out code does not conditionally return. If your function doesn't need to call itself, and it doesn't return a value of any importance, change the return type to void to indicate it has no return value.
Since you are using C99, you can take advantage of using the static keyword in your function's parameter declaration:
void k_vector_calculation(int krec[static 3])
{
// ... other code here ...
krec[0] = l*u[0]+m*v[0]+o*[0];
krec[1] = l*u[1]+m*v[1]+o*[1];
krec[2] = l*u[2]+m*v[2]+o*[2];
}
The above code declares a function that takes as an argument an array of at least 3 int.
Several issues, here:
As Sourav Ghosh pointed out, you define k_vector_calculation(), but then try to call getk_vector_calculation(). You have to use the right names.
You say you want to "get an array from another function" - you just can't do this in C.
You don't show all your code for k_vector_calculation(), but as shown, this function will call itself forever, because the last thing it does is to unconditionally call itself again. If you have a recursive function, you need to give it a way to terminate.
&krec[3] is the address of the fourth element of the array k, which is not want you want to be doing, here, especially since your array only contains 3 elements. To refer to the array itself, just use krec.
char krec[3] = getk_vector_calculation(&krec[3]); is invalid for numerous reasons. One, you can't initialize arrays in this way in C. Two, see point (4) for your argument. Three, even if you could initialize arrays this way in C, you'd be trying to pass an uninitialized array to a function, initialize it in there, and then try to initialize your original array with the result. It just makes no sense.
You also write your functions to work with an array of int, but declare krec in main() as an array of char.
It's not clear what you want k_vector_calculation() to do, but you just can't return arrays in C like that. Probably what you want to do is just pass the array to the function, have the function work on in, and return nothing. For instance:
#include <stdio.h>
void k_vector_calculation(int kvec[])
{
kvec[0] = 1;
kvec[1] = 2;
kvec[2] = 3;
}
int main(void)
{
int kvec[3];
k_vector_calculation(kvec);
for ( int i = 0; i < 3; ++i ) {
printf("kvec[%d] is %d.\n", i, kvec[i]);
}
return 0;
}

Can a two-dimensional array in C be initialized without explicit size?

I have a question regarding two-dimensional arrays in C. I know now (from direct compiler experience) that I can't initialize such an array analogously to one-dimensional arrays like this:
int multi_array[][] = {
{1,2,3,4,5},
{10,20,30,40,50},
{100,200,300,400,500}
};
> compiler output:
gcc -o arrays arrays.c
arrays.c: In function ‘main’:
arrays.c:8:9: error: array type has incomplete element type
The closest solution that works is to provide the number of columns explicitly like this:
int multi_array[][5] = {
{1,2,3,4,5},
{10,20,30,40,50},
{100,200,300,400,500}
};
My question is: can it be done neatly without supplying the number explicitly (which after all the compiler should be able to infer itself)? I'm not talking about manually constructing it with malloc or something but rather something close to what I tried.
Also, can someone knowledgeable about C compilers explain from a low-level perspective why my initial attempt does not work?
I used plain gcc with no non-standard options to compile the code.
Thanks
2D arrays in C are stored in contiguous memory locations. So if you do not provide the number of rows or the number of columns, how will the compiler know how many rows and column there are?
For a row major matrix, rows contents are at contiguous memory positions. So you need to specify at least the number of columns. Similarly for a column major matrix, you need to specify at least the number of rows. Whether it is row major or column major is defined by architecture. It seems that what you have is a row major architecture.
You can do this using the C99 compound literal feature.
A partial idea is that the length of an initializer list can be determined like this:
sizeof (int[]){ 1, 2, 3, 4, 5 } / sizeof(int)
We need a workaround for the fact that the only way you can pass an argument containing a comma to a macro is to put parentheses around (part of) the argument:
#define ROW(...) { __VA_ARGS__ }
Then the following macro deduces the second dimension from the first row:
#define MAGIC_2DARRAY(type, ident, row1, ...) \
type ident[][sizeof (type[])row1 / sizeof (type)] = { \
row1, __VA_ARGS__ \
}
It only works if there are at least two rows.
Example:
MAGIC_2DARRAY(int, arr, ROW(7, 8, 9), ROW(4, 5, 6));
You probably do not want to use this in a real program, but it is possible.
For passing this kind of array to functions, the C99 variable length array feature is useful, with a function like:
void printarr(int rows, int columns, int array[rows][columns]) { ... }
called as:
printarr(sizeof arr / sizeof arr[0], sizeof arr[0] / sizeof arr[0][0], arr);
Not a direct answer to those questions in the original post, I just want to point out that what the asker propose may be not such a good or useful idea.
The compiler indeed can infer from
int multi_array[][] = {
{1,2,3,4,5},
{10,20,30,40,50},
{100,200,300,400,500}
};
the structure of multi_array.
But when you want to declare and define a function (this declaration and definition could be in another compilation unit or source file) that supposes to accept multi_array as one of its argument, you still need to do something like
int foo(..., int multi_array[][COL], ...) { }
Compiler needs this COL to do proper pointer arithmetic in foo().
Usually, we define COL as a macro that will be replaced by an integer in a header file, and use it in the definitions of multi_array and foo():
int multi_array[][COL] = { ... };
int foo(..., int multi_array[][COL], ...) { }
By doing this, it is easy to make sure they are the same. And let compiler to infer the structure of multi_array according to its initialization, when you give it a wrong initialization, you actually introduce a bug in your code.
No you can't do it. If you even don't initialize, you can't define an int array[][];
Create a structure with 1d arrays. However, if you follow this method you can create new arrays but it will be a function call to change sizes and values. A dynamic matrix approach could come close to solving your issue.

Why should I declare a C array parameter's size in a function header?

Can anyone enlighten me as to why I should bother to specify the size of a C array argument in a function header? For example:
void foo (int iz[6]) { iz[42] = 43; }
With:
int is[2] = {1,2,3};
we get a useful error. Perhaps it helps with commenting/documentation?
Can anyone enlighten me as to why I should bother to specify the size of a C array argument in a function header? For example:
void foo (const char sz[6]) { sz[42] = 43; }
IMO, you shouldn't. When you try to pass an array to a function, what's really passed is a pointer to the beginning of the array. Since what the function receives will be a pointer, it's better to write it to make that explicit:
void foo(char const *sz)
Then, since it's now clear that the function has been given no clue of the size, add that as a separate parameter:
void foo(char const *sz, size_t size)
The only meaningful reason to do that is for documentation purposes - to tell the future users that functions expect to receive an array of at least that many elements. But even that is a matter of convention - something that you have to agree upon with other users in advance. The language (the compiler) ignores that size anyway. Your function declaration is equivalent to void foo(int iz[]) and to void foo(int *iz).
The only way to make it somewhat meaningful for the compiler is to declare it as
void foo (int iz[static 6])
which acts as a promise to the compiler that the array will have at least 6 elements, meaning that the compiler will be able to optimize that code using that assumption. Moreover, if you really want to adopt the convention mentioned above, it makes more sense to declare array parameter sizes with static specifically, since the language explicitly defines the semantics of this construct.
What you mean by "we get a useful error" is not clear to me. The code
int is[2] = {1,2,3};
is[42] = 42;
does not contain any constraint violations. It produces undefined behavior, but it is not required to produce a diagnostic message during compilation. In other words, no, we don't get any "useful error" from this.
It's a comment. Arrays are demoted to pointers in function parameters. Comments can still be useful however, even if the compiler doesn't read them.
It is a useful comment when you want to tell to client code that it must pass an array of defined size, i.e:
void foo(const char bar[5]);
/* It is expected that foo function receives an array of size 5 */
Yet, documentation doesn't replace in code checks:
void foo(const char bar[5])
{
if (!bar) error();
if (strlen(bar) != 4) error();
/* ... */
}

Resources