Re: pr_debug and "if (0)" statement

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Frederic Weisbecker wrote:
On Thu, Sep 03, 2009 at 09:25:40AM +0200, luca ellero wrote:
Bernd Petrovitsch ha scritto:
On Wed, 2009-09-02 at 15:17 +0530, Anuz Pratap Singh Tomar wrote:

On Wed, Sep 2, 2009 at 2:30 PM, Bernd Petrovitsch <bernd@xxxxxxxxx>
wrote:
        On Wed, 2009-09-02 at 13:31 +0530, Anuz Pratap Singh Tomar
        wrote:
        > that part of code wont be executed.
[...]
        Then why not simply use "do { } while (0)" or similar?
                [
        > On Wed, Sep 2, 2009 at 1:24 PM, luca ellero
        <lroluk@xxxxxxxxx> wrote:
        [...]
        >         can someone please explain me the meaning/benefits
        of the "if
        >         (0)" statement?
#if 0 is equivalent to blank, this is done while preprocessing, this
type of macro is used commonly to define some sort of debug(print
statement) and if i am not wrong do{}while(0) will execute atleast once.
Yes, of course. Sorry, I meant an empty "do{}while(0)" (or similar
expression) which evaluates as a syntactic correct C expression.

BTW the "if(0)" above (and "#if 0" and an empty "do{}while(0)") have
also the issue that side effects (function calls, ++, --, += -=, ...) in
the parameters of the printk() get lost (which may be good[0] or bad).

That shouldn't be a problem in the Linux kernel as that is generally
avoided but in general that maybe a problem.

	Bernd

[0]: It may be even good if the side effects are just there for the
     printk() as such (e.g. formatting some data into a string just for
     the printk/syslog/printf) but irrelevant for the "normal" program
     flow.

Thanks to all for the answers.
If you don't mind I have another question:
why is there the "0;" statement after the call to printk?


To return a value.

printk is supposed to return the number of characters.
If you don't do anything like here, then you are supposed to return
0.

The following statement:

{
	//do something
}

Won't return any value.

But if you do:

({
	//do something
	//do something else
	//do the last thing
})

That will be evaluated as the value in the last thing done.
Note the parenthesis, they are here to evaluate the whole statement
and return the value of the last expression in the bloc.

That's how we can build macros that simulate functions behaviour
which return values.

Say you define the following:

#define DOUBLE(x) {	\
	x + x;		\
}

And then later:

y = DOUBLE(1);

That won't build because DOUBLE won't return any value.
But that will work if you define it like this:

#define DOUBLE(x) ({	\
	x + x;		\
})

And since we can have:

nr_written = pr_debug("something_to_write");

We wan't to return a value, even if w do nothing, or
it won't even build.



#ifdef DEBUG
/* If you are writing a driver, please use dev_dbg instead */
#define pr_debug(fmt, arg...) \
       printk(KERN_DEBUG fmt, ##arg)
#else
#define pr_debug(fmt, arg...) \
       ({ if (0) printk(KERN_DEBUG fmt, ##arg); 0; })
#endif



Thank you a lot Frederic.
Your explanation was really clear.





--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux