mixture of string and number in macro - c

I want to use this macro to put (if 'i' is greater than zero) the symbol '^' and the number I pass (i) to the macro
#define ESP(i) ((i>0) ? ("^"(i)) : "")
I want to call it in this way
printf("%+d%s", n1, ESP(i));
where 'i' is the index of a cycle, but the compilation reports me errors;
how can I modify the code to be right?

Somewhat dirty but should work:
#include <stdio.h>
#define DYNFORMAT(n, i) (i>0) ?"%+d%s%d\n" :"%+d%s%s\n", n, (i>0) ?"^" :"", (i>0) ?i :""
int main(void)
{
int i = 0;
printf(DYNFORMAT(42, i));
i = 1;
printf(DYNFORMAT(42, i));
}
This should print:
+42
+42^1
Disclaimer: I am not sure whether this conforms to the Standard and how to get rid of the warning(s) it gives during compilation.
The clean approach would be to use two calls to printf().
This can be implemented as a macro or a function.
As I love the pre-processor, the macro version here:
#define PRINT_ESP(n, i) \
do { \
if (i = 0) \
printf("%+d", n); \
else \
printf("%+d^%d", n, i); \
} while (0);

Macros operate at compile time, not at run time. They can perform a variety of text-mangling tricks, but they do not evaluate anything. (They can certainly, however, expand to code that evaluates something.) Putting the formatted value of variable i into a string involves evaluating i; no macro can do this.
You could instead expand the scope of the macro to include the whole printf() call:
#define PRINT_ESP(n1, i) do { \
printf(((i > 0) ? "%+d^%d" : "%+d"), n1, i); \
} while (0)
Alternatively, you could use a macro to express just the format selection incorporated into the above macro definition, or you could just put the full printf() call above directly into your code.
All of these variations are based on the fact that arguments in excess of those required by the given format are evaluated prior to the call, but ignored by printf() itself.

You don't need the (i) after the "^". Change your macro to this and it should work #define ESP(i) ((i>0) ? ("^") : ("")). Then in your printf statement if you want to print the value of i after the "^" then have something like this printf("%s%d", ESP(i), i); As far as I know I don't think you can format a string to include an integer inside a macro since that would require calling other functions, so you have to bring the i into the string inside your printf.

Related

Defining a function as macro

I am trying to understand defining functions as macros and I have the following code, which I am not sure I understand:
#define MAX(i, limit) do \
{ \
if (i < limit) \
{ \
i++; \
} \
} while(1)
void main(void)
{
MAX(0, 3);
}
As I understand it tries to define MAX as an interval between 2 numbers? But what's the point of the infinite loop?
I have tried to store the value of MAX in a variable inside the main function, but it gives me an error saying expected an expression
I am currently in a software developing internship, and trying to learn embedded C since it's a new field for me. This was an exercise asking me what the following code will do. I was confused since I had never seen a function written like this
You are confused because this is a trick question. The posted code makes no sense whatsoever. The MAX macro expands indeed to an infinite loop and since its first argument is a literal value, i++ expands to 0++ which is a syntax error.
The lesson to be learned is: macros are confusing, error prone and should not be used to replace functions.
You have to understand that before your code gets to compiler, first it goes through a preprocessor. And it basically changes your text-written code. The way it changes the code is controlled with preprocessor directives (lines that begin with #, e.g. #include, #define, ...).
In your case, you use a #define directive, and everywhere a preprocessor finds a MAX(i, limit) will be replaced with its definition.
And the output of a preprocessor is also a textual file, but a bit modified. In your case, a preprocessor will replace MAX(0, 3) with
do
{
if (0 < 3)
{
0++;
}
} while(1)
And now the preprocessor output goes to a compiler like that.
So writing a function in a #define is not the same as writing a normal function void max(int i, int limit) { ... }.
Suppose you had a large number of statements of the form
if(a < 10) a++;
if(b < 100) b++;
if(c < 1000) c++;
In a comment, #the busybee refers to this pattern as a "saturating incrementer".
When you see a repeated pattern in code, there's a natural inclination to want to encapsulate the pattern somehow. Sometimes this is a good idea, or sometimes it's fine to just leave the repetition, if the attempt to encapsulate it ends up making things worse.
One way to encapsulate this particular pattern — I'm not going to say whether I think it's a good way or not — would be to define a function-like macro:
#define INCR_MAX(var, max) if(var < max) var++
Then you could say
INCR_MAX(a, 10);
INCR_MAX(b, 100);
INCR_MAX(c, 1000);
One reason to want to make this a function-like macro (as opposed to a true function) is that a macro can "modify its argument" — in this case, whatever variable name you hand to it as var — in a way that a true function couldn't. (That is, if your saturating incrementer were a true function, you would have to call it either as incr_max(&a, 10) or a = incr_max(a, 10), depending on how you chose to set it up.)
However, there's an issue with function-like macros and the semicolon at the end. I'm not going to explain that whole issue here; there's a big long previous SO question about it.
Applying the lesson of that other question, an "improved" INCR_MAX macro would be
#define INCR_MAX(var, max) do { if(var < max) var++; } while(0)
Finally, it appears that somewhere between your exercise and this SO question, the while(0) at the end somehow got changed to while(1). This just about has to have been an unintentional error, since while(1) makes no sense in this context whatsoever.
Yeah, there's a reason you don't understand it - it's garbage.
After preprocessing, the code is
void main(void)
{
do
{
if ( 0 < 3 )
{
0++;
}
} while(1);
}
Yeah, no clue what this thing is supposed to do. The name MAX implies that it should evaluate to the larger of its two arguments, a la
#define MAX(a,b) ((a) < (b) ? (b) : (a))
but that's obviously not what it's doing. It's not defining an interval between two numbers, it's attempting to set the value of the first argument to the second, but in a way that doesn't make a lick of sense.
There are three problems (technically, four):
the compiler will yak on 0++ - a constant cannot be the operand of the ++ or -- operators;
If either i or limit are expressions, such as MAX(i+1, i+5) you're going to have the same problem with the ++ operator and you're going to have precedence issues;
assuming you fix those problems, you still have an infinite loop;
The (technical) fourth problem is ... using a macro as a function. I know, this is embedded world, and embedded world wants to minimize function call overhead. That's what the inline function specifier is supposed to buy you so you don't have to go through this heartburn.
But, okay, maybe the compiler available for the system you're working on doesn't support inline so you have to go through this exercise.
But you're going to have to go to the person who gave you this code and politely and respectfully ask, "what is this crap?"

Defining C macros in preprocessor if statements

Below I change the value of the function that I call depending on the value of INPUT:
#include <stdio.h>
#define INPUT second
#if INPUT == first
#define FUNCTOCALL(X) first(X)
#elif INPUT == second
#define FUNCTOCALL(X) second(X)
#endif
void first(int x) {
printf("first %d\n", x);
}
void second(int x) {
printf("second %d\n", x);
}
int main() {
FUNCTOCALL(3);
return 0;
}
However, the output is first 3, even if INPUT is equal to second, as above. In fact, the first branch is always entered, regardless of the value of INPUT. I'm completely stumped by this - could someone explain what stupid mistake I'm making?
The c preprocessor only works on integer constant expressions in its conditionals.
If you give it tokens it can't expand (such as first or second where first and second aren't macros)
it'll treat them as 0 and 0 == 0 was true last time I used math. That's why the first branch is always taken.
6.10.1p4:
... After all replacements due to macro expansion and the defined
unary operator have been performed, all remaining identifiers
(including those lexically identical to keywords) are replaced with
the pp-number 0, and then each preprocessing token is converted into a
token. ...
You have no macros first and second defined. Be aware that the pre-processor is not aware of C or C++ function names!* In comparisons and calculations (e. g. #if value or #if 2*X == Y), macros not defined (not defined at all or undefined again) or defined without value evaluate to 0. So, as first and second are not defined, INPUT is defined without value, and the comparison in both #if expressions evaluates to 0 == 0...
However, if you did define the two macros as needed, they would collide with the C function names and the pre-processor would replace these with the macro values as you just defined them, most likely resulting in invalid code (e. g. functions named 1 and 2)...
You might try this instead:
#define INPUT SECOND
#define FIRST 1
#define SECOND 2
#if INPUT == FIRST
#define FUNCTOCALL(X) first(X)
#elif INPUT == SECOND
#define FUNCTOCALL(X) second(X)
#else
# error INPUT not defined
#endif
Note the difference in case, making the macro and the function name differ.
* To be more precise, the pre-processor is not aware of any C or C++ tokens, so it does not know about types like int, double, structs or classes, ... – all it knows is what you make it explicitly aware of with #define, everything else is just text it operates on and, if encountering some known text nodes, replacing them with whatever you defined.

Difference between macros and Functions in C language

I'm new to C language. When I'm learning C language I learn something called macros. As I understood macros are like a functions in JavaScript that we can call when we needed. But then I learn that after compiling the program all the places that i have called to macros are replaced by the definition of the macro. So I'm confusing what is the difference between macro and a function in C language.
Also I wanna know whether I can write multi line macros in my code and if it is possible how it will be replaced when the code compiled.
As a example assume that I wanna macro to find the maximum value among two numbers.
Is it a good practice to write that process as a macro rather than write is as a function.
Everything stands - don't use macro. A better alternative inline the function - it would achieve the same efficiency you expect. But for fun, I worked a bit to use gcc statement expressions that means a non-portable gcc centric solution.
#include <stdio.h>
#define SUM(X) \
({ long s = 0; \
long x = (X) > 0 ? (X) : (-(X)); \
while(x) { \
s += x % 10; \
x /= 10; \
} \
s; \
})
int main(void) {
printf("%ld\n",SUM(13423) );
return 0;
}
This solution begs for a function. Using statement expression to have that return something feature inside macro. Well I said, go for inline function. That would serve the purpose much cleaner way.
Using macros is sometimes dangourous:
https://gcc.gnu.org/onlinedocs/cpp/Macro-Pitfalls.html#Macro-Pitfalls
you can read on the dangers of using it here..
but, for your question:
#include <stdio.h>
#define SUM(X, Y) (X + Y)
void main() {
printf("the sum of 3,4 is : %d\n", SUM(3,4));
}
will output:
the sum of 3,4 is : 7

Why am I getting errors while compiling this code and how to fix them?

The program I'm trying to write includes a macro to round a real number to the nearest integer and a function which uses that macro to round an array of real numbers.
Here's the program:
#include <stdio.h>
#define SIZE 256
#define round(N) { return (N >=0)? (int)(N+0.5) : (int)(N-0.5) ; }
void round_array(int a[])
{
int i;
for(i=0; i <SIZE; i++)
{
a[i] = round(a[i]);
}
}
int main()
{
return 0;
}
While compiling, I'm getting these errors:
round.c: In function ���round_array���:
round.c:4:18: error: expected expression before ���{��� token
#define round(N) { return (N >=0)? (int)(N+0.5) : (int)(N-0.5) ; }
^
round.c:11:15: note: in expansion of macro ���round���
a[i] = round(a[i]);
^
round.c: At top level:
Why am I getting these errors and how can I fix them?
Because after preprocessing, your code will look similar to that:
a[i] = { return (a[i] >=0)? (int)(a[i]+0.5) : (int)(a[i]-0.5) ; }
If you like to stick to macro, declare it as:
#define round(N) ((N) >=0)? (int)((N)+0.5) : (int)((N)-0.5)
But this is still not really correct because of int/float mixing. That is however already a different topic.
Like it was told to you in a comment, macros aren't functions. They are a token substitution mechanism. So you do not return from them as you would a function.
#define round(N) (((N) >=0)? (int)((N)+0.5) : (int)((N)-0.5))
The changes I made include:
Making it an expression. This involves replacing the curly braces with parentheses. This is so you could use the macro almost anywhere you could use a function. Had I left the curly braces it would have been a compound statement.
Wrapping the parameter N in parentheses as well, to make sure operator precedence doesn't come back and bite us.
Macro-replacement is basically what it sounds like, it replaces the macro with the body of the macro, quite literally.
So when you have
a[i] = round(a[i]);
It will be replaced by
a[i] = { return (a[i] >=0)? (int)(a[i]+0.5) : (int)(a[i]-0.5) ; };
That's not valid syntax. The right-hand side of an assignment must be an expression and not a statement.
A simple solution is to turn round from a macro to an actual function. An even simpler solution is to realize that int values (a[i] is an int) doesn't have fractions, so there's nothing to round.
If you want to use floating-point values though, the correct solution is to use the standard round function, not to make up your own.
If you insist on writing this yourself, you should replace the icky macro with a safer, cleaner function:
inline int int_round (double d)
{
return (int) ( d >= 0 ? d+0.5 : d-0.5 );
}
This should yield the very same machine code.
You don't need the return keyword, it's not a function. Get rid of it.
Quoting C11, chapter §6.8.6.4
A return statement terminates execution of the current function and returns control to
its caller. [...]
which is not the purpose of your MACRO definition. Inclusion of return keyword is unwanted and invalid syntax there.
What you probably want is a syntax like
(N >=0)? (int)(N+0.5) : (int)(N-0.5)
or, something better
( (N) >=0)? (int)((N)+0.5) : (int)((N)-0.5)
without the return and maybe the trailing ; also.

Using macro to check null values

My C code contains many functions with pointers to different structs as parameters which shouldn't be NULL pointers. To make my code more readable, I decided to replace this code:
if(arg1==NULL || arg2==NULL || arg3==NULL...) {
return SOME_ERROR;
}
With that macro:
NULL_CHECK(arg1,arg2,...)
How should I write it, if the number of args is unknown and they can point to different structs? (I work in C99)
IMO the most maintainable solution is to write multiple separate calls rather than trying to get "clever" about it.
for example, Win32 programmers use a VERIFY macro which runs an assertion at debug time (the macro ensures that the assertions are stripped out of release code); It's not unusual to see functions which start like this:
int foo(void* arg1, char* str, int n)
{
VERIFY( arg1 != NULL );
VERIFY( str != NULL );
VERIFY( n > 0 );
Obviously, you could very easily condense those 3 lines into a single line, but the macro works best when you don't. If you put them onto separate lines, then a failed assertion will tell you which of the three conditions have not been met, whereas putting them all in the same statement only tells you that something has failed, leavng you to figure out the rest.
If you decide to use a macro, then I recommend using a macro that takes a single argument:
#define NULL_CHECK(val) if (val == NULL) return SOME_ERROR;
You can then write:
NULL_CHECK(s1.member1);
NULL_CHECK(p2->member2);
Etc. One of the advantages is that you can incorporate error reporting or logging accurately to identify the first invalid member like this. With a single composite condition, you only know that at least one of them is invalid, but not exactly which one.
If you must deal with a variable number of arguments, then you need to investigate Boost::Preprocessor, which will work in C as well as C++.
Not that I think it's a great idea to hide a return statement inside a macro, but such a macro could be written like:
#define NULL_CHECK(...) \
do { \
void *_p[] = { __VA_ARGS__ }; \
int _i; \
for (_i = 0; _i < sizeof(_p)/sizeof(*_p); _i++) { \
if (_p[_i] == NULL) { \
return SOME_ERROR; \
} \
} \
} while(0)
Basically, expand the varargs into an array and loop over the indexes.

Resources