Re: pr_debug and "if (0)" statement

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

 



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
>
>
> Thanks
>
> Luca
>
>
> --
> To unsubscribe from this list: send an email with
> "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
> Please read the FAQ at http://kernelnewbies.org/FAQ
>


--
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