Prepend function call with some code using Macro in C - c

I have a call to a function foo(a,b,c) in a C file which I want to prepend with some code. Can I do this with macro? Basically, I want to do the following:
Replace
add(a,b,c)
by
foo()
add(a,b,c)
Is it possible to achieve this with macro?

#include <stdio.h>
int add(int a, int b, int c) {
return a + b + c;
}
void foo() {
printf("Foo!\n");
}
int add2(int a, int b, int c) {
foo();
return add(a, b, c);
}
#define add(a, b, c) add2((a), (b), (c))
int main() {
printf("%d\n", add(5, 3, 1));
return 0;
}

As macros don't expand recursively, the following is possible:
#define add(a, b, c) ( foo() , add((a), (b), (c)) )
The add in the replacement refers to the function, not the macro. This approach, however, has a few pitfalls: Taking the address and using a function pointer will refer to the real function, not the macro, as would enclosing add in parentheses as in (add)(a, b, c).

Sure you can define a macro
#define foo(a,b,c) {foo(); add(a,b,c);}

If C++ inline function is not an option then use comma operator:
#define bar(a, b, c) (foo(), add((a), (b), (c)))

Related

nested macro implementation with # and ## operator

I am writing a generic function which will take macro name and execute correct function.
I am writing a function which will take function name from macro and concatenate this and execute the function.I am adding this header file in my workspace where more than one c file use this macro implementation logic to execute my code.But I am getting error while running the code .
#define STR(name) #name
int convert_f14u18(int a,int b);
int convert_f14s18(int a,int b);
#define VAL_F 14
#define DATA_SIGN u
#define VAL_NUM 18
#define EXECUTE_FUN_NAME(a,b,c,d,e) a##b##c##d##e
#define EXECUTE_STATEMENT(a,b,c,d,e,f) b##c##d##e#f=EXECUTE_FUN_NAME(a,b,c,d,e)
typedef int u32;
u32 add_u32(u32 a,u32 b);
int main() {
//Testing of string macro
printf(STR(Hello));
int numa = 10;
int numb = 20;
int numc = 30;
//int z1 = EXECUTE_FUN_NAME(convert_,f,14,u,18)(numa,numb);
int z1 = EXECUTE_FUN_NAME(convert_,f,VAL_F,DATA_SIGN,VAL_NUM)(numa,numb);
//int z2 = EXECUTE_FUN_NAME(convert_,f,14,s,18)(numa,numc);
int z2 = EXECUTE_FUN_NAME(convert_,f,VAL_F,DATA_SIGN,VAL_NUM)(numa,numc);
printf("\nz1 %d\n",z1);
printf("z2 %d\n",z2);
return 0;
}
int convert_f14u18(int a,int b){
return (a+b);
}
int convert_f14s18(int a,int b){
return (a+b);
}
u32 add_u32(u32 a,u32 b){
return (a+b);
}
Error:../main.cpp: In function ‘int main()’:
../main.cpp:37:76: error: ‘convert_fVAL_FDATA_SIGNVAL_NUM’ was not declared in this scope
int z1 = EXECUTE_FUN_NAME(convert_,f,VAL_F,DATA_SIGN,VAL_NUM)(numa,numb);
Expected result: If I un-comment the lines above of actual macro statement in main statements and comment the current macro statements, I am able to run the code. But I want to make my code run with the current logic .
When replacing a macro, C first replaces each parameter with its argument. So the argument c is replaced with VAL_F, for example. Then it applies the ## operator, which produces convert_fVAL_FDATA_SIGNVAL_NUM in this example. Then C checks the result for additional macros to substitute. However, at that point, the arguments, such as VAL_F, have been made into a single token with ## and are no longer individual tokens that will be replaced.
To deal with this, use one macro to replace the arguments, then use another macro to apply the ## operator. Change:
#define EXECUTE_FUN_NAME(a,b,c,d,e) a##b##c##d##e
to:
#define EXECUTE_FUN_NAME_HELPER(a, b, c, d, e) a##b##c##d##e
#define EXECUTE_FUN_NAME(a, b, c, d, e) EXECUTE_FUN_NAME_HELPER(a, b, c, d, e)

Simplest way to use default argument in C

I need to create a function in which there is a default argument:
void func ( int a, int b = 1 );
// and
func (1, 2);
func (1);
C doesn't support default arguments, though you can sometimes hack something like them using the preprocessor:
void func(int a, int b);
#define TWO_ARGS(A, B, ...) A, B
#define func(...) func(TWO_ARGS(__VA_ARGS__, 1))
func(1, 2); /* calls func(1, 2); */
func(1); /* calls func(1, 1); */
It's really simple. There is no default argument in c, the code is invalid. You can always use c++ which has default arguments and are very useful. But in c there is no way to achieve that.

How do I call a c macro from an assembly routine?

I have a macro X that does some stuff like this.
#define X(a,b,c) \
a.foo = b; \
a.bar = c;
I want to call X from an assembly routine, like so:
.data
pushl $eax;
call X(a, b, c);
Is there a way to do this?
A macro is not a function, which means it does not have an address, thus you can not call it.
Macros are evaluated by the preprocessor. Using them just results in a simple text replacement, as a result they only exist in the source file and nowhere else.
However, what you could do is set up a wrapper function for the macro and call it instead. Like so:
#define X(a, b, c) (a).foo = (b); \
(a).bar = (c)
void _X(struct foo *a, int b, int c)
{
X(*a, b, c);
}
But that just removes the need for a macro in the first place. So you might as well get rid of the macro and use a function.

max of two integers using ternary operator in C

Is there a better way to return the max of two integers using the ternary operator in C?
This is what I have for now
int max(int a, int b)
{
int big = 0;
big = (a>b)?a:b;
return big;
}
But I wanted to write it something like this
#include <stdio.h>
int main(void)
{
printf("%d\n",fun(5,4));
return 0;
}
int fun(int a, int b)
{
(a>b)?(return a:return b);
}
But it gives me an error
The conditional operator (yes, it has a name!) is used to build expressions, so you have to use it where an expression is expected – for example, the expression of the return statement:
return b < a ? a : b;
One improvement you can do is make the function inline
inline int max(int a, int b) {
return a > b ? a : b;
}
See Also An Inline Function is As Fast As a Macro.
return is a statement, not an expression. It can't be used in the middle of an expression.
Also, the two return values of the ternary have to be separate expressions; wrapping them in a single set of parentheses makes them just one expression.
So it should be:
int fun(int a, int b) {
return (a > b) ? a : b;
}

How to pass a macro as an argument in a C function?

I want to pass a macro as an argument in a C function, and I don't know if it possible.
I would like to see this operation, for instance:
I have these macros:
#define PRODUCT(A, B) ((A) * (B))
#define SUM(A, B) ((A) + (B))
And then I have this function with the following signature:
int just_a_function(int x, MACRO_AS_PARAMATER_HERE);
and then i want to call this function like:
just_a_function(10, SUM);
is it possible?
Thanks
You can't pass as function argument.
But if function is a macro this is possible.
#include <stdio.h>
#define PRODUCT(A, B) ((A) * (B))
#define SUM(A, B) ((A) + (B))
#define JUST_A_FUNCTION(A, B, MACRO) MACRO(A, B)
int main() {
int value;
value = JUST_A_FUNCTION(10, 10, SUM);
printf("%d\n", value);
value = JUST_A_FUNCTION(10, 10, PRODUCT);
printf("%d\n", value);
return 0;
}
You can't do that.
Use normal functions instead:
int sum(int x, int y)
{
return x+y;
}
//...
just_another_function(10, sum);
Note: just_another_function must accept int (*)(int, int) as the second argument.
typedef int (*TwoArgsFunction)(int, int);
int just_another_function(int x, TwoArgsFunction fun);
Hi what you are passing is macro means its a substitution your passing . Think about it ..
Ex : #define HIGH 1
In a function you can use int variable. So you can pass 1 to the function . In a function its stored as integer variable
Preprocessor directive works first . Once in a main macro are replaced means in the sense in a function you have to take care of the substitution. If I would have used Macro High 1 ,, in function I will take as int as a argument to get for local function stack. For better understanding check the topics 1.preprocessor directive 2. How the hex file created once you will compile
#include <stdio.h>
#define HIGH 1
#define LOW 0
void pin(int, int);
void pin(int a, int b) {
printf("A: %d B: %d\n", a, b);
}
int main() {
pin(1, HIGH);
return 0;
}
Compilation step involve:
pre processor directive
compiler
linker
executable file

Resources