#define
s in Kernel files use
a do { <code> } while 0;
construct?" This
piqued my interest.The basic reason why is that if you have a define like:
#define exch(x,y) { int t; t = x; x = y; y = t; }And you have use it in code such as:
if (x > y) exch(x,y); else x = 0;Then this gets expanded to:
if (x > y) { int t; t = x; x = y; y = t; }; # End of if statement here else # dangling else x = 0;Now, yes, this is bad. But to me it's bad because the programmer has fallen for C's lazy statement syntax and assumed that the 'then' clause of the if statement is always going to be a single statement. This type of construct fails regularly because if you have to add some other statement to that if/then/else statement, like:
if (x > y) exch(x,y); call_foobar(x,y); else x = 0;Then you've fallen for the same trap. Once again, the
exch()
call completes the if
statement and the
call_foobar()
call is executed unconditionally. Indenting
in this case is worse than a sham, it actively deceives the programmer
into thinking that the logic will work when it won't. Of course, if
the programmer had initially written:
if (x > y) { exch(x,y); } else { x = 0; }Then it would all make sense, the
#define
would work, the
extra statements added in would work. What's a couple of extra
characters and an extra brace line, compared to many hours hunting
down an elusive bug? Lazy programming is good in certain circumstances,
but it doesn't excuse bad style or the hubris of thinking you'll never
have to revise or debug this piece of code.I know I'll have already put some people offside by commenting on this coding practice. But if and when I ever have to write something for the kernel I'll be using a sensible amount of braces, thank you.
Last updated: | path: tech / c | permanent link to this entry
All posts licensed under the CC-BY-NC license. Author Paul Wayper.
Main index
/ tbfw/
- © 2004-2023
Paul Wayper
Valid HTML5