kernelnewbies.kernelnewbies.org archive mirror
 help / color / mirror / Atom feed
* Understanding #ifdef in .h files
@ 2014-06-20 10:58 Harold André
  2014-06-20 11:06 ` Pranay Srivastava
  0 siblings, 1 reply; 5+ messages in thread
From: Harold André @ 2014-06-20 10:58 UTC (permalink / raw)
  To: kernelnewbies

Hi,

I try to understand how #ifdef in .h files works.

I read Greg Kroah-Hartman's Coding style paper
http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/mgp00031.html

And as he says, i try to do a simple example but it does not work. I
try with a small piece of C outside the kernel. I have 3 files.


test_ifdef.h:

	#ifdef TEST_FUNCTION
	void test(int *value);
	#else
	static inline void test(int *value) { }
	#endif

test_ifdef.c:

	#include "test_ifdef.h"

	void test(int *value)
	{
	    *value += 1;
	}

main.c:

	#include <stdio.h>
	#include "test_ifdef.h"

	int main(int argc, char *argv[])
	{
	    int i = 3;
	
	    printf("i = %d\n", i);

	    test(&i);

	    printf("i = %d\n", i);

	    return 0;
	}


And when i compile:

$ gcc -Wall -g main.c test_ifdef.c -o test_ifdef -DTEST_FUNCTION
$ ./test_ifdef 
i = 3
i = 4
$ gcc -Wall -g main.c test_ifdef.c -o test_ifdef
test_ifdef.c:14:6: error: redefinition of ?test?
 void test(int *value)
      ^
In file included from test_ifdef.c:12:0:
test_ifdef.h:17:20: note: previous definition of ?test? was here
 static inline void test(int *value) { }
                    ^
$

I understand why it does not compile. But:
- How it can work in the kernel code ?
- Is-it possible to do this in code outside the kernel ?

Thank you.

Harold

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Understanding #ifdef in .h files
  2014-06-20 10:58 Understanding #ifdef in .h files Harold André
@ 2014-06-20 11:06 ` Pranay Srivastava
  2014-06-20 12:59   ` Harold André
  0 siblings, 1 reply; 5+ messages in thread
From: Pranay Srivastava @ 2014-06-20 11:06 UTC (permalink / raw)
  To: kernelnewbies

Hi Harold

On 6/20/14, Harold Andr? <harold.andre@gmx.fr> wrote:
> Hi,
>
> I try to understand how #ifdef in .h files works.
>
> I read Greg Kroah-Hartman's Coding style paper
> http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/mgp00031.html
>
> And as he says, i try to do a simple example but it does not work. I
> try with a small piece of C outside the kernel. I have 3 files.
>
>
> test_ifdef.h:
>

You say here you will define the function else where if TEST_FUNCTION is defined

> 	#ifdef TEST_FUNCTION
> 	void test(int *value);
> 	#else
> 	static inline void test(int *value) { }
> 	#endif
>
> test_ifdef.c:
>
> 	#include "test_ifdef.h"
>
But here you do on and define it any way. You must stick to the rule
you created earlier. If you are defining it here then this must also
be under the test of ifdef TEST_FUNCTION
> 	void test(int *value)
> 	{
> 	    *value += 1;
> 	}
>
> main.c:
>
> 	#include <stdio.h>
> 	#include "test_ifdef.h"
>
> 	int main(int argc, char *argv[])
> 	{
> 	    int i = 3;
> 	
> 	    printf("i = %d\n", i);
>
> 	    test(&i);
>
> 	    printf("i = %d\n", i);
>
> 	    return 0;
> 	}
>
>
> And when i compile:
>
> $ gcc -Wall -g main.c test_ifdef.c -o test_ifdef -DTEST_FUNCTION
> $ ./test_ifdef
> i = 3
> i = 4
> $ gcc -Wall -g main.c test_ifdef.c -o test_ifdef
> test_ifdef.c:14:6: error: redefinition of ?test?
>  void test(int *value)
>       ^
> In file included from test_ifdef.c:12:0:
> test_ifdef.h:17:20: note: previous definition of ?test? was here
>  static inline void test(int *value) { }
>                     ^
> $
>
> I understand why it does not compile. But:
> - How it can work in the kernel code ?
> - Is-it possible to do this in code outside the kernel ?
>
> Thank you.
>
> Harold
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>


-- 
        ---P.K.S

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Understanding #ifdef in .h files
  2014-06-20 11:06 ` Pranay Srivastava
@ 2014-06-20 12:59   ` Harold André
  2014-06-20 13:14     ` Pranay Srivastava
  0 siblings, 1 reply; 5+ messages in thread
From: Harold André @ 2014-06-20 12:59 UTC (permalink / raw)
  To: kernelnewbies

Le Fri, 20 Jun 2014 16:36:58 +0530,
Pranay Srivastava <pranjas@gmail.com> a ?crit :


> You say here you will define the function else where if TEST_FUNCTION
> is defined
> 
> > 	#ifdef TEST_FUNCTION
> > 	void test(int *value);
> > 	#else
> > 	static inline void test(int *value) { }
> > 	#endif
> >
> > test_ifdef.c:
> >
> > 	#include "test_ifdef.h"
> >
> But here you do on and define it any way. You must stick to the rule
> you created earlier. If you are defining it here then this must also
> be under the test of ifdef TEST_FUNCTION
> > 	void test(int *value)
> > 	{
> > 	    *value += 1;
> > 	}
> >

Thank you Pranay for your answer. I understand this now.

But when i look at the kernel code, i don't see ifdef test around the
definition of the function. For example, i look for the function
"hiddev_hid_event":

In include/linux/hiddev.h:
#ifdef CONFIG_USB_HIDDEV
...
void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
			struct hid_usage *usage, __s32 value);
...
#else
...
static inline void hiddev_hid_event(struct hid_device *hid, struct
hid_field *field, struct hid_usage *usage, __s32 value) { }
...
#endif

In drivers/hid/usbhid/hiddev.c:
/*
 * This is where hid.c calls into hiddev to pass an event that occurred
over
 * the interrupt pipe
 */
void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
		      struct hid_usage *usage, __s32 value)
{
	unsigned type = field->report_type;
	struct hiddev_usage_ref uref;

	uref.report_type =
	  (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
	  ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
	   ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE :
	0)); uref.report_id = field->report->id;
	uref.field_index = field->index;
	uref.usage_index = (usage - field->usage);
	uref.usage_code = usage->hid;
	uref.value = value;

	hiddev_send_event(hid, &uref);
}
EXPORT_SYMBOL_GPL(hiddev_hid_event);

And in drivers/hid/hid-core.c:
...

	if (hid->claimed & HID_CLAIMED_INPUT)
		hidinput_hid_event(hid, field, usage, value);
	if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt &&
	hid->hiddev_hid_event)
		hid->hiddev_hid_event(hid, field, usage, value);
...

If i'm right. The function "hiddev_hid_event" is always defined in
"hiddev.c" whatever "CONFIG_USB_HIDDEV" is defined or not ?
How is it possible ?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Understanding #ifdef in .h files
  2014-06-20 12:59   ` Harold André
@ 2014-06-20 13:14     ` Pranay Srivastava
  2014-06-20 13:58       ` Harold André
  0 siblings, 1 reply; 5+ messages in thread
From: Pranay Srivastava @ 2014-06-20 13:14 UTC (permalink / raw)
  To: kernelnewbies

On Fri, Jun 20, 2014 at 6:29 PM, Harold Andr? <harold.andre@gmx.fr> wrote:
> Le Fri, 20 Jun 2014 16:36:58 +0530,
> Pranay Srivastava <pranjas@gmail.com> a ?crit :
>
>
>> You say here you will define the function else where if TEST_FUNCTION
>> is defined
>>
>> >     #ifdef TEST_FUNCTION
>> >     void test(int *value);
>> >     #else
>> >     static inline void test(int *value) { }
>> >     #endif
>> >
>> > test_ifdef.c:
>> >
>> >     #include "test_ifdef.h"
>> >
>> But here you do on and define it any way. You must stick to the rule
>> you created earlier. If you are defining it here then this must also
>> be under the test of ifdef TEST_FUNCTION
>> >     void test(int *value)
>> >     {
>> >         *value += 1;
>> >     }
>> >
>
> Thank you Pranay for your answer. I understand this now.
>
> But when i look at the kernel code, i don't see ifdef test around the
> definition of the function. For example, i look for the function
> "hiddev_hid_event":
>
> In include/linux/hiddev.h:
> #ifdef CONFIG_USB_HIDDEV
> ...
> void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
>                         struct hid_usage *usage, __s32 value);
> ...
> #else
> ...
> static inline void hiddev_hid_event(struct hid_device *hid, struct
> hid_field *field, struct hid_usage *usage, __s32 value) { }
> ...
> #endif
>
> In drivers/hid/usbhid/hiddev.c:
> /*
>  * This is where hid.c calls into hiddev to pass an event that occurred
> over

That's right but the magic doesn't happen here :-)

if you see usbhid/Makefile you'll understand what I mean :-). If not ,
please do ask.


>  * the interrupt pipe
>  */
> void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
>                       struct hid_usage *usage, __s32 value)
> {
>         unsigned type = field->report_type;
>         struct hiddev_usage_ref uref;
>
>         uref.report_type =
>           (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
>           ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
>            ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE :
>         0)); uref.report_id = field->report->id;
>         uref.field_index = field->index;
>         uref.usage_index = (usage - field->usage);
>         uref.usage_code = usage->hid;
>         uref.value = value;
>
>         hiddev_send_event(hid, &uref);
> }
> EXPORT_SYMBOL_GPL(hiddev_hid_event);
>
> And in drivers/hid/hid-core.c:
> ...
>
>         if (hid->claimed & HID_CLAIMED_INPUT)
>                 hidinput_hid_event(hid, field, usage, value);
>         if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt &&
>         hid->hiddev_hid_event)
>                 hid->hiddev_hid_event(hid, field, usage, value);
> ...
>
> If i'm right. The function "hiddev_hid_event" is always defined in
> "hiddev.c" whatever "CONFIG_USB_HIDDEV" is defined or not ?
> How is it possible ?



-- 
        ---P.K.S

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Understanding #ifdef in .h files
  2014-06-20 13:14     ` Pranay Srivastava
@ 2014-06-20 13:58       ` Harold André
  0 siblings, 0 replies; 5+ messages in thread
From: Harold André @ 2014-06-20 13:58 UTC (permalink / raw)
  To: kernelnewbies

Le Fri, 20 Jun 2014 18:44:35 +0530,
Pranay Srivastava <pranjas@gmail.com> a ?crit :

> On Fri, Jun 20, 2014 at 6:29 PM, Harold Andr? <harold.andre@gmx.fr>
> wrote:
> > Le Fri, 20 Jun 2014 16:36:58 +0530,
> > Pranay Srivastava <pranjas@gmail.com> a ?crit :
> >
> >
> >> You say here you will define the function else where if
> >> TEST_FUNCTION is defined
> >>
> >> >     #ifdef TEST_FUNCTION
> >> >     void test(int *value);
> >> >     #else
> >> >     static inline void test(int *value) { }
> >> >     #endif
> >> >
> >> > test_ifdef.c:
> >> >
> >> >     #include "test_ifdef.h"
> >> >
> >> But here you do on and define it any way. You must stick to the
> >> rule you created earlier. If you are defining it here then this
> >> must also be under the test of ifdef TEST_FUNCTION
> >> >     void test(int *value)
> >> >     {
> >> >         *value += 1;
> >> >     }
> >> >
> >
> > Thank you Pranay for your answer. I understand this now.
> >
> > But when i look at the kernel code, i don't see ifdef test around
> > the definition of the function. For example, i look for the function
> > "hiddev_hid_event":
> >
> > In include/linux/hiddev.h:
> > #ifdef CONFIG_USB_HIDDEV
> > ...
> > void hiddev_hid_event(struct hid_device *hid, struct hid_field
> > *field, struct hid_usage *usage, __s32 value);
> > ...
> > #else
> > ...
> > static inline void hiddev_hid_event(struct hid_device *hid, struct
> > hid_field *field, struct hid_usage *usage, __s32 value) { }
> > ...
> > #endif
> >
> > In drivers/hid/usbhid/hiddev.c:
> > /*
> >  * This is where hid.c calls into hiddev to pass an event that
> > occurred over
> 
> That's right but the magic doesn't happen here :-)
> 
> if you see usbhid/Makefile you'll understand what I mean :-). If not ,
> please do ask.

Ah yes !! Ok, i understand !! ;-)
Thank Pranay for sharing your knowledge !

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-06-20 13:58 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-20 10:58 Understanding #ifdef in .h files Harold André
2014-06-20 11:06 ` Pranay Srivastava
2014-06-20 12:59   ` Harold André
2014-06-20 13:14     ` Pranay Srivastava
2014-06-20 13:58       ` Harold André

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).