2

I read this in include/linux/sched.h:

#define __set_task_state(tsk, state_value)              \
    do { (tsk)->state = (state_value); } while (0)

I know that when it comes to multi-statement in a body, a do {...} while (0) should be used. But that is just one statement in the body, is it really necessary to use do {...} while (0)? How about just as follows:

#define __set_task_state(tsk, state_value)              \
    ((tsk)->state = (state_value))
Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
password636
  • 981
  • 1
  • 7
  • 18
  • @trojanfoe I'm asking about one-statement body, is it involved in that topic? – password636 Apr 28 '16 at 09:48
  • Yes; have you looked at it? – trojanfoe Apr 28 '16 at 09:49
  • 1
    @trojanfoe Would you please let me know the specific part or the answer concerning one-statement body? I looked at the answers again and still didn't get it. Thank you. – password636 Apr 28 '16 at 10:16
  • You're correct, it doesn't have any answers about any single statement bodies. – Viliami Apr 28 '16 at 10:20
  • 1
    Ah I see what you mean; apologies. I think you'll probably find that `do { ... } while(0)` is being used in the linux headers regardless of the number of statements within the "loop". This makes it easy to change to two-or-more statements later. – trojanfoe Apr 28 '16 at 10:22
  • 2
    @trojanfoe Ok, I get it. Thank you for answering. Should my topic still be duplicate? Or change it to normal so that other people won't skip or miss something here. – password636 Apr 28 '16 at 10:27
  • 2
    It's should not be a duplicate, however you need to flag for moderator attention to make that happen, sorry. My comment is also incorrect as I've just checked the linux kernel coding conventions and `do/while` is only mentioned when multiple statements are used within a macro. – trojanfoe Apr 28 '16 at 10:29
  • 1
    Sheesh. Hey, black, Vasfed, and Basile Starynkevitch: He's already explained that it's *not* a duplicate. The linked questions don't answer the sub-question, "Why would you use this technique for the body of a single-statement macro?" AIUI, the question has already been closed, and reopened, once already, and now you guys closed it again. Double Jeopardy! – Steve Summit Apr 28 '16 at 16:14

1 Answers1

1

It's true that when the body of the macro is a single statement or expression (as here), the use of the do { ... } while(0) trick is less compelling. There's not nearly as much wrong with

#define __set_task_state(tsk, state_value)              \
    ((tsk)->state = (state_value))

But I suspect we could still come up with cases where this "simpler" definition might cause problems, such that the do/while trick would still be advantageous. For example, if you accidentally wrote

__set_task_state(a, b)
do_something_else;

the error message you'd get for the missing semicolon might be less confusing in the do/while case. (Or not.)

In general, of course, function-like macros are often problematic, and inline functions are recommended. I can't say why an inline function wasn't used here. (There are certainly plenty of them elsewhere in the Linux kernel sources.)

Steve Summit
  • 45,437
  • 7
  • 70
  • 103