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.
Related
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?"
so i have a marco function like so:
#define PROPOGATE_METHOD(status, function, propogationMethod) \
status = function; \
if(status != eSuccess)\
{\
propogationMethod; \
}
So like any good developer would do, I want to wrap each of the parameters as such :
#define PROPOGATE_METHOD(status, function, propogationMethod) \
(status) = (function); \
if((status) != eSuccess)\
{\
(propogationMethod); \
}
But if I call this macro function with a goto or return, I get an error (expecting expression before goto).
i.e. PROPOGATE_METHOD(status, functionCall(), goto Error;);
Thoughts on working around this? I was thinking of moving the goto into the macro function, and wrapping around the label, but that throws another error :
expected identifier or ‘*’ before ‘(’ token
So like any good developer would do, I want to wrap each of the parameters as such
#StoryTeller had a good response to this in comment section. " A good developer understands why the suggestion exists, what problem it solves, and most importantly, when it's not applicable. Blindly doing something is not good development.".
Another good applicable quote is "Blindly following best practices is not best practice".
Here, it really seems like you're adding parenthesis because someone said "it's a good thing to put parenthesis around the arguments". Not because of any valid purpose in this particular case.
Skip the macro
I don't really see the purpose with this macro. TBH, it looks like you're showing off, but macros like this are very likely to cause hard traced bugs. If it's just to save some lines, you can actually make a somewhat decent oneliner of this without any macro.
if((status = foo()) != eSuccess) goto Error;
or
if((status = foo()) != eSuccess) return x;
or
if((status = foo()) != eSuccess) bar();
In many cases, I'd prefer making those on two or three lines. But the above is not so bad. And I would definitely say that it's better than the macro. Just remember the extra parenthesis around status = foo(). If forgetting this is a big concern, you could do something like this:
int foo_wrapper(int *status) { return *status = foo(); }
...
if(foo_wrapper(&status) != eSuccess) goto Error;
or even:
int status_assign(int *dest, int src) { return *dest = src; }
...
if(status_assign(&status, foo()) != eSuccess) goto Error;
On the other hand, it shouldn't be a problem, because if you compile with -Wall, which you should, you will get this:
warning: suggest parentheses around assignment used as truth value
Personally, I don't think it's extremely important with braces when it's single statements, but if you want a oneliner with braces, well just do:
if((status = foo()) != eSuccess) { goto Error; }
Some will like it. Some will not, but it's not the most important question in the world. But I would prefer any of the above before the macro you're suggesting.
Compare these:
PROPOGATE_METHOD(status, foo(), goto Error;);
if((status = foo()) != eSuccess) goto Error;
When compared side by side, I cannot really see that the macro accomplishes anything at all. It doesn't make anything clearer or safer. Without the macro, I can see EXACTLY what's happening and I don't need to wonder about that. Macros have their uses, but as far as I can see here, this is not one of them.
From comments below
I understand. i'm going through and refactor a code base. i prefer not to littler the code base with these if statements and prefer the macro statement because
I can understand that, but I would really encourage you to reconsider. At least if you're allowed to do it. If I were to refactor that code base, getting rid of that macro would have pretty high priority. After all, what refactoring is, is to rewrite code so it becomes better with focus on design and readability. If you don't want to do it, put parenthesis around status and function and then leave it. It will not make it good, but it will not cause any harm either.
I would not use this expression if it were you who had written that macro, but since it's not you, I can use it. "Fixing" that macro is really polishing a turd. No matter what you do, it will never shine, and it will always be a turd.
Disregarding if that macro is useful or confusing, and the merits of goto, consider what the parens inside a macro/define are for. If you have say, this:
#define FOO a + b
...
int y = x * FOO;
what you end up with, is y = x * a + b (because it's just text replacement, not a real variable), which is the same as y = (x * a) + b. Hence, putting parens around (a + b) in FOO fixes that.
This, of course has a similar problem (both inside x and outside the macro), with a similar solution:
#define FOO2(x) x * 123
...
int y = FOO2(a + b);
Now, you have
#define BAR(x) { x };
is there a similar problem there? What should x include that the parenthesis would remove a similar problem stemming from operator precedence? I don't really see such an issue, in a way, the braces already work to protect the x part from the code surrounding the macro. Adding the parens has just the effect of forcing x to be an expression, instead of a full statement.
The goto statement (goto label;) isn't an expression, so you cannot parenthesize it (and neither is goto label without the ;, which isn't even a separately recognizable construct in C's syntax).
And even if you passed something that you can parenthesize (e.g., longjmp(jbuf,1)), there isn't much of a point in parenthesizing it in this context ({ HOOK; }).
Now if you expanded it in a context like HOOK_EXPR * 2, then parentheses would be useful to force HOOK_EXPR to group tighter than * (imagine you passed 3+4 as HOOK_EXPR), but in this context you don't need them.
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.
What should be done for DD ?
if
#define HEADING_TITLE_PROJECT_NAME "<= Version Maintenance Based On Compiled DateTime =>"
#define SIZE_OF_HEADER_FOR_DECORATION_PURPOSE sizeof(HEADING_TITLE_PROJECT_NAME)
#define DD ????
#define HEADING "\r\n"DD"\r\n"HEADING_TITLE_PROJECT_NAME"\r\n"DD"\r\n"
I want to get HEADING string literal as follows:
<==================================================>
<= Version Maintenance Based On Compiled DateTime =>
<==================================================>
The = sign or anything I put once will repeat within <== ... ==> to fill the HEADING_TITLE_PROJECT_NAME space.
Can it be done this way or other.
I only want to change the HEADING_TITLE_PROJECT_NAME in coding time and nothing else.
JUST THOUGHT IF IT CAN BE DONE
:)
<==Edit start==>
Something like
#define DD\
char * get()\
{\
char arr[100] = '\0';\
for (int i=0; i < SIZE_OF_HEADER_FOR_DECORATION_PURPOSE - 1; i++)\
{\
arr[i] = "=";\
}\
return arr;\
}
<==Edit ends==>
Unfortunately, there's no automatic way to generate DD in the standard C preprocessor, as long as you want to use it the way you use in the definition of HEADING macro.
As long as you insist of having that HEADING defined they way it is currently defined, I can only suggest using a semi-automatic approach :). Define DD manually, explicitly.
#define HEADING_TITLE_PROJECT_NAME "<= Version Maintenance Based On Compiled DateTime =>"
#define DD "<==================================================>"
And then just add
STATIC_ASSERT(sizeof HEADING_TITLE_PROJECT_NAME == sizeof DD);
right under it (with your favorite implementation of STATIC_ASSERT). That way any discrepancy in DD's length will immediately trigger an error and force the developer to update the DD.
This is impossible because of sizeof is evaluated after the preprocessor, rather than before.
If you knew the length of the string in advance, it would be.
Because the proprocessor doesn't have any looping constructs, you wind up creating them. Boost does it something like this
#define REPEAT_TIMES(macro, n) REPEAT##n(macro)
#define REPEAT1(macro) MACRO
#define REPEAT2(macro) REPEAT1(macro)MACRO
#define REPEAT3(macro) REPEAT2(macro)MACRO
....
You would then simply:
#define FILLER "="
#define DD "<"REPEAT_TIMES(FILLER, 34)">"
Your implementation of DD isn't a bad idea, though it suffers from some poor syntax and undefined behavior.
const char *DDD(void)
{
static char arr[] = HEADING_TITLE_PROJECT_NAME;
if(arr[2] == ' ')
for(size_t i = 2; i + 3 < sizeof arr; i++)
arr[i] = '=';
return arr;
}
#define DD DDD()
You can't return a pointer to stack data, so you have to use a static array. We can make sure it's the right size by having it automatically set to the #defined string, then checking if it's been filled with '=' yet and, if not, fill it. Then we return a const pointer to it so that no one tries to modify it.
Your macro defines a function, get, with unspecified arguments, and returning a modifiable char * to stack data. Unfortunately, this function will be defined everywhere you use the macro, which will result in many multiple definition errors.
You can't use this with raw string concatenation, but it will work for everything else you want.
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
What’s the use of do while(0) when we define a macro?
Why are there sometimes meaningless do/while and if/else statements in C/C++ macros?
C multi-line macro: do/while(0) vs scope block
I have seen a lot of usages like this, previously I though that the programmer wanted to break out of a block of code easily. Why do we need a do { ... } while (0) loop here? Are we trying to tell the compiler something?
For instance in Linux kernel 2.6.25, include/asm-ia64/system.h
/*
* - clearing psr.i is implicitly serialized (visible by next insn)
* - setting psr.i requires data serialization
* - we need a stop-bit before reading PSR because we sometimes
* write a floating-point register right before reading the PSR
* and that writes to PSR.mfl
*/
#define __local_irq_save(x) \
do { \
ia64_stop(); \
(x) = ia64_getreg(_IA64_REG_PSR); \
ia64_stop(); \
ia64_rsm(IA64_PSR_I); \
} while (0)
It's always used in macros so that a semicolon is required after a call, just like when calling a regular function.
In your example, you have to write
__local_irq_save(1);
while
__local_irq_save(1)
would result in an error about a missing semicolon. This would not happen if the do while was not there. If it was just about scoping, a simple curly brace pair would suffice.
It allows for the code to appear here:
if(a) __local_irq_save(x); else ...;
// -> if(a) do { .. } while(0); else ...;
If they simply used a { .. } you would get
if(a) { ... }; else ...;
The else would not belong to any if anymore, because the semicolon would be the next statement and separate the else from the preceeding if. A compile error would occur.
The purpose of do{ ... } while(0) construct is to turn a group of statements into a single compound statement that can be terminated with a ;. You see, in C language the do/while construct has one weird and unusual property: even though it "works" as a compound statement, it expects a ; at the end. No other compound constructs in C have this property.
Because of this property, you can use do/while to write multi-statement macros, which can be safely used as "ordinary" functions without worrying what's inside the macro, as in the following example
if (/* some condition */)
__local_irq_save(x); /* <- we can safely put `;` here */
else
/* whatever */;
The answer has already been given (so the macro forces a ; when called), but another use of this kind of statement that I have seen: it allows break to be called anywhere in the "loop", early terminating if needed. Essentially a "goto" that your fellow programmers wouldn't murder you for.
do {
int i = do_something();
if(i == 0) { break; } // Skips the remainder of the logic
do_something_else();
} while(0);
Note that this is still fairly confusing, so I don't encourage its use.
Looks like it's there just for scoping. It's similar to:
if (true)
{
// Do stuff.
}
edit
I don't see it in your example, but it's possible that one of those function calls is actually a macro, in which case there's one key difference between do/while(0) and if(true), which is that the former allows continue and break.
It makes use of the macro act like a real statement or function call.
A statement is either { expression-list } or expression; so that poses a problem when defining macros that need more than one expression, because if you use { } then a syntax error will occur if the caller of the macro quite reasonably adds a ; before an else.
if(whatever)
f(x);
else
f(y);
If f() is a single statement macro, fine, but what if it's a macro and something complicated? You end up with if(...) { s1; s2; }; else ... and that doesn't work.
So the writer of the macro has to then either make it into a real function, wrap the construct in a single statement, or use a gnu extension.
The do .. while(0) pattern is the "wrap the construct" approach.