Can I really make a function like macro - c

Here is an example:
#define get_i() i
int i;
int i2;
i2 = get_i();
In the case above ^^^ get_i() acts like a function that returns something(the value ofi in this case).
#define set_i(value) do{i = (value);}while(0)
set_i(i2);
This ^^^ above acts like a function that DO NOT return.
My question is, can I use macros to create a function-like macro that can both, do something, and return an object? Here is a pseudo code:
#define increse_i2_and_return_i() i2++; return i;
Is that possible?

You can use comma operator for that. The value of the last operand will be the value of an entire expression.
#define increse_i2_and_return_i() (i2++, i)
The downside of this trick is that you can't create temporary variables in a such macro.

Related

Prepocessor ## Operator and variable

Is there a way to "generate" a function name by using the operator ## and a variable value. For example:
#define FUN_I(fun, fun_id) fun##fun_id
#define FUN(fun, fun_id) RECV_CB_FUN_I(fun, fun_id)
int foo0(int x) {
// do something
}
int main()
{
int i = 0;
FUN(foo,i)(1);
}
Macro FUN generates fooi. Is there a way to get foo0 somehow, or I have to use the actual number 0 in this case, e.g FUN(foo, 0)(1);
Cheers
You have to use actual 0 (or another macro). Macro expansion is handled by the C pre-processor at compile time. It knows nothing about runtime values of variables.
As stated, the macro expansion is done at compile time, so the function name wouldn't be know at run time.
It is more appropriate to use function pointers and an array to them.
Example:
typedef int (*TFoo)(int);
int foo1(int x)
{
printf("from foo1: x = %d\n", x);
return 0;
}
int foo2(int x)
{
printf("from foo2: x = %d\n", x);
return 0;
}
TFoo foos[2] = {foo1, foo2};
#define foo(i, x) foos[i](x)
That's that. Hope it helps
'c' preprocessing is a process of replacing macros with the text from their definitions. some operations like ## allow to add its argument as text into definitions. So, everything is done even before compilation starts.
As a result, in your case FUN(fun,i) will be substituted as text and form funi. The only limited way to build function names like you want is to use actual text values or other macros. Here are 2 examples which will work with pre-processing:
FUN(fun, 0)(1);
or
#define I 0
FUN(fun, I)(1);
In the last case I is a macro itself, therefore it also works. (it is always a good idea to name macro name in upper case letters).

C preprocessor init array

I'm writing a complex macro and I need to pass also array initializer. Basically I have trouble to do:
#define INIT_ARR(VAR_NAME,ARR_DATA) int VAR_NAME[] = ARR_DATA
then I would call it
INIT_ARR(myNm,{1,2,3});
but preprocessors interprets any commas (also the one inside curly braces) as new macro parameter so it gives me error:
error: #55-D: too many arguments in invocation of macro "INIT_ARR"
preprocessor does not ignore () so I can do:
#define INIT_ARR(VAR_NAME,ARR_DATA) int VAR_NAME[] = {ARR_DATA}
INIT_ARR(myNm,(1,2,3));
but then it is interpreted as
int myNm[] = {(1,2,3)};
which is not correct for C.
Is there a way how to do it?? For example remove braces from parameter?
I think I cracked it:
#define myArgs(...) __VA_ARGS__
#define INIT_ARR(VAR_NAME,ARR_DATA) int VAR_NAME[] = {myArgs ARR_DATA}
INIT_ARR(myArr,(1,2,3,4));
will be interpreted correctly as:
int myArr[] = {1,2,3,4};
annoying_squid's answer helped me to figure it out...
You can use variable number of arguments with the macro as -
#define INIT_ARR(VAR_NAME, ...) int VAR_NAME[] = {__VA_ARGS__}

Calling Inline Function in Macro Preprocessor of a C Program

I am confused by the following macro pre-processor definition:
#define HOOK_SYSCALL(NAME) original_##NAME = get_sys_call_table_addr()[__NR_##NAME];
The code for the function named get_sys_call_table_addr() is as follows:
ssize_t *sys_call_table = (ssize_t *)NULL;
void** get_sys_call_table_addr(void)
{
void *swi_addr=(long *)0xffff0008;
unsigned long offset=0;
unsigned long *vector_swi_addr=0;
offset=((*(long *)swi_addr)&0xfff)+8;
vector_swi_addr=*(unsigned long *)(swi_addr+offset);
while(vector_swi_addr++)
{
if(((*(unsigned long *)vector_swi_addr)& 0xfffff000)==0xe28f8000)
{
offset=((*(unsigned long *)vector_swi_addr)& 0xfff)+8;
sys_call_table=(void *)vector_swi_addr+offset;
break;
}
}
return (void **) sys_call_table;
}
I'd like to ask whether this specific line:
get_sys_call_table_addr()[__NR_##NAME];
is calling the inline function as an array? Like what we'd do to a normal kind of array, e.g. array[3];
Thanks!!
## is used to concatenate preprocessor tokens. Suppose the NAME is exit. Then get_sys_call_table_addr()[__NR_##NAME] will be
get_sys_call_table_addr()[__NR_exit]. This means that get_sys_call_table_addr() is called and the evaluated result will be a pointer.
Remember that arr[x] is *(arr + x). Let's say that __NR_exit is a constant with a value 1. Then, the resultant pointer returned by the function is moved by 1 and then dereferenced. This will now be assigned to the variable original_exit.
the token ## is used to concatenate two tokens into one. For example in the above example __NR_##NAME becomes __NR_NAME.
The function get_sys_call_table_addr() returns a table sys_call_table, which is a double pointer. This table shall be used as a array variable and points to address pointed by [__NR_NAME].
In otherwords, get_sys_call_table_addr()[__NR_##NAME] becomes sys_call_table[__NR_NAME];

How to return value from C macro?

I was trying to implement the sizeof() operator, and wanted the macro to return the result like the one provided by C lang.
I implemented it using gcc construct '()' like:
#define SIZEOF(type)\
({\
int result;\
type *p = 0;\
result = (char*)(p+1)-(char*)p;\
result;\
})
And used it like this:
x = SIZEOF(double);
Is there any way to do it without using gcc construct and returning value from that?
The best i can think of is pass another parameter to macro and store result in that like:
#define SIZEOF(type,result)\
do{\
type *p = 0;\
result = (char*)(p+1)-(char*)p;\
}while(0)
I know that I can replace this macro with inline function which will do the work but was looking for something in macro context. Is there any way to achieve this?
#define SIZEOF(type) (long int) (((type*)0) + 1)

Can the name of function and function-like macro be same?

Can the name of function and function-like macro be same?
Wouldn't this cause any problem?
They could be the same. Depending on how you use the name, either it gets replaced by preprocessor or not. For example
//silly but just for demonstration.
int addfive(int n)
{
return n + 5;
}
#define addfive(n) ((n) + 5)
int main(void)
{
int a;
a = addfive(2); //macro
a = (addfive)(2); //function
}
for ex. MS says that: http://msdn.microsoft.com/en-us/library/aa272055(v=vs.60).aspx
http://gcc.gnu.org/onlinedocs/cpp/Function-like-Macros.html#Function-like-Macros
Here you can see that calling the function, of which a macro with the same name exists, calls the macro instead :)
For the gcc at least!
This would cause no problem, but quite some confusions. I wouldn't recommend this.
I will explain via cases:
If you declared the function first then the function like macro second, macro will over take the function. i.e. it will be called always instead of the function.
//Function
double squar(double x)
{
return x*x;
}
//Macro
#define squar(x) (x*x)
On the other hand if you declare the macro first then the function later, an exception will be arise, you wont be able to build
//Macro
#define squar(x) (x*x)
//Function
double squar(double x)
{
return x*x;
}
At the end, in the first case, you still call the function like #Hayri Uğur Koltuk said here in his answer by (squar)(5)

Resources