Linux Kernel defines everywhere - c

On linux's kernel we can find this piece of code in linux/sched.h, when I saw it some doubts came to my mind:
Why using define to create functions? Why not using the normal return-type function-name(par1, par2) {} style?
What is the point with the do {} while(0)?
#define set_special_state(state_value)
do {
unsigned long flags;
raw_spin_lock_irqsave(&current->pi_lock, flags);
current->state = (state_value);
raw_spin_unlock_irqrestore(&current->pi_lock, flags);
} while (0)
#endif

This isn't a "function", it's a preprocessor macro.
Sometimes one must use macros to do things that the C language itself doesn't support (usually generating code). This doesn't look like one of those cases though, and should probably be a static inline function. Pergaps the Git history would explain why it is the way it is.
do { ... } while (0) is a common method for swallowing the semicolon which follows a call to a C-function-looking macro like this one.

Functions are usually preferrable because they provide type checking and aren't error prone to things like double evaluation, but macros are more powerful, since they allow you to work at the text/token level.
do{}while(0) is to make an invoked macro grammatically behave like a void-returning function call.
You might think a plain pair of curlies would do that but that doesn't work
with if-else
#define macro_with_curlies() { }
if(x) macro_with_curlies(); else { }
//expands to: if(x) { }; /*else is illegal after the semicolon*/ else { }

Related

Practical differences between "do {...} while (0)" and "{...} ((void)0)" in macros?

It's common practice in C to use:
#define FOO() do { /* body */ } while (0)
While this is fine, it's also possible to do:
#define FOO() { /* body */ }((void)0)
{...}((void)0) has many of the same benefits: you can't accidentally merge logic, and a ; is required at the end of the line, so odd expressions like this don't go by un-noticed: FOO() else {...}.
The only difference I've noticed is it means you need to use braces in if-statements.
if (a)
FOO();
else
BAR();
Must be written as:
if (a) {
FOO();
} else {
BAR();
}
Other then this quirk, it seems to work well, preventing the same kinds of problems do/while method is typically used for.
Are there any significant differences between the 2 methods?
Said differently, if you see a code-base using {...}((void)0), are practical reasons to switch to using do{..}while(0), besides the one difference already noted?
The practical difference is exactly what you pointed out.
The do { ... } while (0) idiom means that the macro can be used in any context that requires a statement.
Your suggested idiom { ... } ((void)0) can be used safely in most contexts that require an expression -- but it can fail if it's used in an unbraced if statement.
I can think of no good reason to use an unfamiliar idiom that almost always works, when there's a well known idiom that always works.
One difference is you can use break with #define FOO() do { /* body */ } while (0) but not with #define FOO() { /* body */ }(void)0.
Let's say you are inside a function, say hello(), and doing something in #define FOO() do { /*some device operation */ } while (0) but some error occurred so you no longer want to proceed with that device but there are other statements in function hello() you want to execute, let's say for another device.
So if you use second statement then you will do return most probably which will exit out of hello() but if you use the first statement you can happily break and do some operation in same function hello() for another device.

Purpose of #define foo() do { } while (0)

While browsing sources of LinCAN driver, I found some macros that baffled me.
#else /*CONFIG_PREEMPT*/
#define can_preempt_disable() do { } while (0)
#define can_preempt_enable() do { } while (0)
#endif /*CONFIG_PREEMPT*/
I understand the usefulness of
do {
...;
if(condition) break;
...
} while (0);
using break as a kind of throw. I semi-understand wrapping a sequence of functions like
#define FOO() do { foo(); bar(); } while (0)
to avoid caveats with braceless if. I understand sometimes "no-op statements" are required for a #define. But why this particular kind? specifically, empty braces, false condition, do...while? Some syntax caveats I can't quite grasp?
It is a common syntax for notifying the compiler that macro should be treated as a statement instead of as an expression (statements vs expressions).
In this case compiler will alert you if you try to use can_preempt_disable() as an expression. This means that we forced compile-time check that can_preempt_disable() is used as a statement. Compile-time checks are very often desirable.
The complete passage from the relevant file is:
#if !defined(CONFIG_PREEMPT_RT) && ( defined(CONFIG_PREEMPT) ||
(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) )
#define can_preempt_disable preempt_disable
#define can_preempt_enable preempt_enable
#else /*CONFIG_PREEMPT*/
#define can_preempt_disable() do { } while (0)
#define can_preempt_enable() do { } while (0)
#endif /*CONFIG_PREEMPT*/
Thus, the first part is the code you get when you've asked for pre-emption protection, otherwise you get the empty, do-nothing, loops.
I guess they're written like that for the usual reasons, i.e. to ensure that the macro still is a valid statement.
There shouldn't be a terminating semicolon in the definition, since that will be in the code using these, such as this function which begins:
int c_can_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
{
can_preempt_disable();
...
So, clearly the macro is used like any other function call, and the semicolon is right there where the macro is invoked. This is very normal.
UPDATE 2: Defining it to a ; leads to double semicolons which is ugly, at least in my opinion. An empty brace pair {} would work I guess, but this do/while construct is even more idiomatic since it's often used in cases like these.
UPDATE 3: As pointed out in a comment, an empty brace pair won't work since then you can't put a semicolon after the call. Aah. Thanks!

Why is this construct used? Mad or genius?

I'm working with a large SDK codebase glommed together from various sources of varying quality / competence / sanity from Linus Torvalds to unidentified Elbonian code slaves.
There are an assortment of styles of code, some clearly better than others, and it's proving an interesting opportunity to expand my knowledge / despair for the future of humanity in alternate measures.
I've just come across a pile of functions which repeatedly use a slightly odd (to me) style, namely:
void do_thing(foo)
{
do {
if(this_works(foo) != success)
break;
return(yeah_cool);
} while (0);
return(failure_shame_death);
}
There's nothing complicated being done in this code (I haven't cut 10,000 lines of wizardry out for this post), they could just as easily do:
if(this_works(foo) == success)
return(yeah_cool);
else
return(failure_shame_death);
Which would seem somehow nicer / neater / more intuitive / easier to read.
So I'm now wondering if there is some (good) reason for doing it the other way, or is it just the way they always do it in the Elbonian Code Mines?
Edit: As per the "possible duplicate" links, this code is not pre-processed in any sort of macro, it is just in the normal code. I can believe it might be due to a coding style rule about error checking, as per this answer.
Another guess: maybe you didn't quote the original code correctly? I have seen the same pattern used by people who want to avoid goto: they use a do-while(0) loop which at the end returns a success value. They can also break out of the loop for the error handling:
int doXandY() {
do {
if (!x()) {
break;
}
if (!y()) {
break;
}
return 0;
} while( 0 );
/* Error handling code goes here. */
globalErrorFlag = 12345;
return -1;
}
In your example there's not much point to it because the loop is very short (i.e. just one error case) and the error handling code is just a return, but I suspect that in the real code it can be more complex.
Some people use the do{} while(0); construct with break; inside the loop to be compliant in some way with MISRA rule 14.7. This rule says that there can be only single enter and exit point in the function. This rule is also required by safety norm ISO26262. Please find an example function:
int32_t MODULE_some_function(bool first_condition,bool second_condition)
{
int32_t ret = -1 ;
do
{
if(first_condition)
{
ret = 0 ;
break ;
}
/* some code here */
if(second_condition)
{
ret = 0 ;
break ;
}
/* some code here */
} while(0) ;
return ret ;
}
Please note however that such a construct as I show above violates different MISRA rule which is rule 14.6. Writing such a code you are going to be compliant with one MISRA rule, and as far as I know people use such a construct as workaround against using multiple returns from function.
In my opinion practical usage of the do{}while(0); construct truely exist in the way you should construct some types of macros.Please check below question, it was very helpful for me :
Why use apparently meaningless do-while and if-else statements in macros?
It's worth notice also that in some cases do{}while(0); construct is going to be completely optimized away if you compile your code with proper optimization option.
Hm, the code might be preprocessed somehow. The do { } while(0) is a trick used in preprocessor macros; you can define them like this:
#define some_macro(a) do { whatever(); } while(0)
The advantage being that you can use them anywhere, because it is allowed to put a semicolon after the while(0), like in your code above.
The reason for this is that if you write
#define some_macro(a) { whatever(); }
if (some_condition)
some_macro(123);
else
printf("this can cause problems\n");
Since there is an extra semicolon before the else statement, this code is invalid. The do { ... } while(0) will work anywhere.
do {...} while(0) arranged with "break" is some kind of "RAII for Plain C".
Here, "break" is treated as abnormal scope exit (kind of "Plain C exceptions"), so you can be sure that there is only one place to deallocate a resource: after a "while(0)". It seems slightly unusual, but actually it's very common idiom in the world of plain C.
I would guess that this code was originally written with gotos for error handling:
void do_thing(foo)
{
if(this_works(foo) != success)
goto error;
return(yeah_cool);
error:
return(failure_shame_death);
}
But at some point an edict came down from on high "thou shalt not use goto", so someone did a semi-automatic translation from goto style to loop-break style (perhaps with simple script). Probably when the code was merged/moved from one project to another.

Evaluate macro parameter once only

In the following code, whatever is passed as retval is evaluated as given for every use of that token.
#define _CPFS_RETURN(commit, retval) do { \
util_cpfs_exit(commit); \
return retval; \
} while (false)
#define CPFS_RETURN_BOOL(retval) do { \
_CPFS_RETURN(retval, retval); \
} while (false)
For example given the use CPFS_RETURN_BOOL(inode && file_truncate(inode, len));, this is generated:
do {
do {
util_cpfs_exit(inode && file_truncate(inode, len));
return inode && file_truncate(inode, len);
} while (0);
} while (0);
Evidently I don't want to execute the statement inode && file_truncate(inode, len); more than once.
How can I ensure that the given tokens are evaluated before being pasted helter-skelter?
Update
I believe I have good reason to use macros here. Where possible, code is put into real functions (such as util_cpfs_exit) which are invoked from a set of macros I'm using. The macros vary based on the return type: in C++ I'd have explicit templates to handle this.
As your macro vary on the return type, you can evaluate the retval expression and store it in a variable of the right type inside the first level of macro then use this variable. ie:
#define CPFS_RETURN_BOOL(retval) do { \
bool _tmp_ = retval;
_CPFS_RETURN(_tmp_, _tmp_); \
} while (false);
If I understand well, that should be enough for your use case, and for other use cases you can use functions.
In your exemple you'll get:
do {
bool _tmp_ = inode && file_truncate(inode, len);
do {
util_cpfs_exit(_tmp_);
return _tmp_;
} while (0);
} while (0);
Looks fine.
PS: as a sidenote if you always use _CPFS_RETURN indirectly through another macro following the above model, there is no need to protect it by a do { } while (false);. Also, putting a semi-colon after the while(false) removes most of the interest of using it... that may be a good example of why C macros are dangerous and hides easy pitfalls. Not that I dislike macros, quite the contrary. I'm from the (probably rare) kind of people that would prefer C macros to be enhanced to bypass their current limitations to become really cool (and no, C++ templates are not enhanced macros, they are something completely different).
I would recommend that you evaluate the condition first.
i.e.
bool val = inode && file_truncate(inode, len);
Other than that may advice would be to steer well clear of macros, they seem unnecessary in this instance, use functions instead.
Write a function instead of using a macro. In this case, where you want to build a return statement in, you might be better off just writing the code explicitly instead of relying on a macro to hide what you're doing.
Change the macro to a "static inline" function. In gcc, it's as fast as a macro.
http://gcc.gnu.org/onlinedocs/gcc/Inline.html

Personal Preprocessor Directives

Being a C novice I would like to hear what Macro "define"s developers are using. I've been thinking about putting these in a header to skip verbosity I've become used to:
#define TS_ typedef struct {
#define _TS(x) } x;
#define I(x)_ { int i; for ( i = 1; i <= x; i++ ) {
#define _I } }
Can I add \n \t etc within these macros? As I would like to pass on my sourcecode minus the extra include:
#define TS_ typedef struct {\n
#define _TS(x) } x;\n
#define I(x)_ { int i;\n\tfor ( i = 1; i <= x; i++ ) {\n
#define _I \t}\n}\n
Would these work?
ie: Can I use the proprocessor to replace my sourcecode with my personal include to formatted source without the include ?
Links to good preprocessor tips and tricks also appreciated.
Before you get started, do not use macro names that begin with an underscore - these are reserved for compiler and standard library writers, and must not be used in your own code.
Additionally, I would say that the macros you suggest are all very bad ideas, because they hide from the reader what is going on. The only justification for them seems to be to save you a very small amount of typing. Generally, you should only be using macros when there is no sensible alternative. In this case there is one - simply write the code.
You can put whitespace in by escaping the newline
#define SOMETHING whatever\
This is part of the macro
But as others have said it's not really a great way to to do this.
It would be much better to look into editor macros so you could type the shortcut and have the editor expand it.
You are headed into a wrong path. DO NOT make up your own cpp directives that are unfamiliar to others - this will make your code hard to understand, and at some point maintain.
Try to find some good C code to read - good C code does not use these things, for a good reason.
DON'T DO IT. Nobody else will be able to read your code.
As a cautionary example, check out Steve Bourne's original sources for the Bourne shell, where he used macros to write the code in a kind of pidgin Algol style.
You could do this, but this sort of "personal language" is not generally used in the C world, especially if you expect anybody else to read your code in the future.
If you're doing this just for yourself, then feel free to #define whatever you want, but expect that once you start working with (or for) anybody else, you won't be able to continue using this sort of thing.
Using C macros unnecessarily can lead you into a world of pain, especially if you attempt to use it to expand code. There are uses for C macros, but this is not it.
Edit: I realize that my answer is tangential to your question, but I thought I should mention this since you say you are a C novice. Search for "C macro pitfalls" to get a full list of reasons why not to use macros. It's been previously discussed here.
In general, I strongly agree with the other respondents who tell you not to define your own macros purely for the sake of saving typing. The obfuscation is not worth it. Also, the particular macros you suggest are heinous. However, in Stroustrup's 1st Ed, he does something I rather like (sometimes):
#define Kase break; case
I became accustomed to the Python elif construct, so I often define the following:
#define elif(test) else if(test)
My purpose in doing this isn't to reduce typing, it's to keep indentation logical while maintaining consistent code width (I don't let my code go wider than 80 characters). I say this because to me this...
if(...) ...
else if(...) ...
else ...
...should be...
if(...)
{
...
}
else
if(...)
{
...
}
else
{
...
}
With my macro this becomes:
if(...)
{
...
}
elif(...)
{
...
}
else
{
...
}
It is always better to pass the loop variable to the macro.
A block - a macro has certain optimization problems. All compilers do not guarantee an optimized obj code for the "block scope" variables.
for example, the following code, when compiled with out any optimization options to gcc, prints two separate addresses for &i. And the same code when compiled with -O2 option will print the same address in both the blocks.
{
int i;
printf("address of i in first block is %u\n", &i);
}
{
int i;
printf("address of i in sec block is %u\n", &i);
}
Naming the language constructs appropriately makes the code more readable.
I like your idea, if you put it in the following way.
#define GREEN 1
#define YELLOW 2
#define RED 3
# define NUM_COLORS 3
#define COLOR_ITER (color,i) \
for(i=GREEN, color = colors[i]; \
i < NUM_COLORS; \
color = colors[++i])
int colors[3] = {GREEN, YELLOW, RED};
int
fun () {
int j;
color_t clr;
COLOR_ITER(clr, j) {
paint(clr);
}
}
Here, regardless of how it is written, the macro, COLOR_ITER, by its name, implies that you are looping for all available colors and doing "something" for each color. And this is a very easy-to-use macro.
And your quesion
Can I use the proprocessor to replace my sourcecode with my personal include to formatted source without the include ?
As everybody explained preprocessor will not help you in this case.
You can use your editor commands to automatically format your code, as you type it.

Resources