LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* typecheck code
@ 2011-01-31 17:03 Sri Ram Vemulpali
  2011-01-31 17:20 ` Jamie Iles
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Sri Ram Vemulpali @ 2011-01-31 17:03 UTC (permalink / raw)
  To: Kernel-newbies, linux-kernel-mail

Hi all,

/*
 * Check at compile time that something is of a particular type.
 * Always evaluates to 1 so you may use it easily in comparisons.
 */
 #define typecheck(type,x) \
 ({      type __dummy; \
        typeof(x) __dummy2; \
        (void)(&__dummy == &__dummy2); \
        1; \
 })

#define typecheck_fn(type,function) \
({      typeof(type) __tmp = function; \
       (void)__tmp; \
})

Can anyone help me, explain the above code typecheck. How does
(void)(&__dummy == &__dummy2) evaluates to 1

I appreciate any explain.

-- 
Regards,
Sri.

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

* Re: typecheck code
  2011-01-31 17:03 typecheck code Sri Ram Vemulpali
@ 2011-01-31 17:20 ` Jamie Iles
  2011-01-31 17:22 ` Geert Uytterhoeven
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Jamie Iles @ 2011-01-31 17:20 UTC (permalink / raw)
  To: Sri Ram Vemulpali; +Cc: Kernel-newbies, linux-kernel-mail

On Mon, Jan 31, 2011 at 12:03:37PM -0500, Sri Ram Vemulpali wrote:
> Hi all,
> 
> /*
>  * Check at compile time that something is of a particular type.
>  * Always evaluates to 1 so you may use it easily in comparisons.
>  */
>  #define typecheck(type,x) \
>  ({      type __dummy; \
>         typeof(x) __dummy2; \

So here we're creating __dummy of the macro specified type and __dummy2 
by using the GCC extensions to work out the type.

>         (void)(&__dummy == &__dummy2); \

This does a comparison and casts the result to void so we ignore the 
result at runtime (and the compiler can optimise it away), but at 
compile time, if the types don't match then we'll get:

	warning: comparison of distinct pointer types lacks a cast

>         1; \

and here we always return 1.

>  })
> 
> #define typecheck_fn(type,function) \
> ({      typeof(type) __tmp = function; \
>        (void)__tmp; \
> })
> 
> Can anyone help me, explain the above code typecheck. How does
> (void)(&__dummy == &__dummy2) evaluates to 1

It's not that comparison that is evaluating to 1, it's the line 
immediately after.  The GCC statement expression extensions [1] mean 
that the "1; \" at the end will always be the value that the macro is 
evaluated to.

Jamie

1. http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html

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

* Re: typecheck code
  2011-01-31 17:03 typecheck code Sri Ram Vemulpali
  2011-01-31 17:20 ` Jamie Iles
@ 2011-01-31 17:22 ` Geert Uytterhoeven
  2011-01-31 17:44 ` Rajat Sharma
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Geert Uytterhoeven @ 2011-01-31 17:22 UTC (permalink / raw)
  To: Sri Ram Vemulpali; +Cc: Kernel-newbies, linux-kernel-mail

On Mon, Jan 31, 2011 at 18:03, Sri Ram Vemulpali
<sri.ram.gmu06@gmail.com> wrote:
> Hi all,
>
> /*
>  * Check at compile time that something is of a particular type.
>  * Always evaluates to 1 so you may use it easily in comparisons.
>  */
>  #define typecheck(type,x) \
>  ({      type __dummy; \
>        typeof(x) __dummy2; \
>        (void)(&__dummy == &__dummy2); \
>        1; \
>  })
>
> #define typecheck_fn(type,function) \
> ({      typeof(type) __tmp = function; \
>       (void)__tmp; \
> })
>
> Can anyone help me, explain the above code typecheck. How does
> (void)(&__dummy == &__dummy2) evaluates to 1

It does not rely on the equation evaluating to 1. That result is
expicitly unused,
witness the cast to void.
It does rely on gcc complaining if you compare two pointers that don't
point to the same type.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: typecheck code
  2011-01-31 17:03 typecheck code Sri Ram Vemulpali
  2011-01-31 17:20 ` Jamie Iles
  2011-01-31 17:22 ` Geert Uytterhoeven
@ 2011-01-31 17:44 ` Rajat Sharma
  2011-01-31 18:03 ` Manish Katiyar
  2011-01-31 20:26 ` Dave Hylands
  4 siblings, 0 replies; 8+ messages in thread
From: Rajat Sharma @ 2011-01-31 17:44 UTC (permalink / raw)
  To: Sri Ram Vemulpali; +Cc: Kernel-newbies, linux-kernel-mail

> Can anyone help me, explain the above code typecheck. How does
> (void)(&__dummy == &__dummy2) evaluates to 1

Its not this comparison getting evaluated to 1, but last expression
"1; \" which is forcibly returning 1 in every case. Since it is just
compile time warning and should not effect the program execution, this
macro is always returning 1 at run time. To me it just valuable for
coding style where you do some action only if type matches, but in
real sense you take action anyways.

Rajat

On Mon, Jan 31, 2011 at 10:33 PM, Sri Ram Vemulpali
<sri.ram.gmu06@gmail.com> wrote:
> Hi all,
>
> /*
>  * Check at compile time that something is of a particular type.
>  * Always evaluates to 1 so you may use it easily in comparisons.
>  */
>  #define typecheck(type,x) \
>  ({      type __dummy; \
>        typeof(x) __dummy2; \
>        (void)(&__dummy == &__dummy2); \
>        1; \
>  })
>
> #define typecheck_fn(type,function) \
> ({      typeof(type) __tmp = function; \
>       (void)__tmp; \
> })
>
> Can anyone help me, explain the above code typecheck. How does
> (void)(&__dummy == &__dummy2) evaluates to 1
>
> I appreciate any explain.
>
> --
> Regards,
> Sri.
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies@kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>

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

* Re: typecheck code
  2011-01-31 17:03 typecheck code Sri Ram Vemulpali
                   ` (2 preceding siblings ...)
  2011-01-31 17:44 ` Rajat Sharma
@ 2011-01-31 18:03 ` Manish Katiyar
  2011-01-31 20:23   ` Sri Ram Vemulpali
  2011-01-31 20:26 ` Dave Hylands
  4 siblings, 1 reply; 8+ messages in thread
From: Manish Katiyar @ 2011-01-31 18:03 UTC (permalink / raw)
  To: Sri Ram Vemulpali; +Cc: Kernel-newbies, linux-kernel-mail

On Mon, Jan 31, 2011 at 9:03 AM, Sri Ram Vemulpali
<sri.ram.gmu06@gmail.com> wrote:
> Hi all,
>
> /*
>  * Check at compile time that something is of a particular type.
>  * Always evaluates to 1 so you may use it easily in comparisons.
>  */
>  #define typecheck(type,x) \
>  ({      type __dummy; \
>        typeof(x) __dummy2; \
>        (void)(&__dummy == &__dummy2); \
>        1; \
>  })
>
> #define typecheck_fn(type,function) \
> ({      typeof(type) __tmp = function; \
>       (void)__tmp; \
> })
>
> Can anyone help me, explain the above code typecheck. How does
> (void)(&__dummy == &__dummy2) evaluates to 1

Infact I think it will never return 1, since the addresses of __dummy1
and __dummy2 have to be different (off by 4 or 8). As pointed out it
is the next line that always returns 1. The purpose of this line is to
throw away warnings like "Incompatible pointer comparison" or
something like that (haven't tried :-)) incase there is a mismatch.

-- 
Thanks -
Manish

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

* Re: typecheck code
  2011-01-31 18:03 ` Manish Katiyar
@ 2011-01-31 20:23   ` Sri Ram Vemulpali
  0 siblings, 0 replies; 8+ messages in thread
From: Sri Ram Vemulpali @ 2011-01-31 20:23 UTC (permalink / raw)
  To: Manish Katiyar; +Cc: Kernel-newbies, linux-kernel-mail

Thanks for all explanation. It really helped to understand.

Sri

On Mon, Jan 31, 2011 at 1:03 PM, Manish Katiyar <mkatiyar@gmail.com> wrote:
> On Mon, Jan 31, 2011 at 9:03 AM, Sri Ram Vemulpali
> <sri.ram.gmu06@gmail.com> wrote:
>> Hi all,
>>
>> /*
>>  * Check at compile time that something is of a particular type.
>>  * Always evaluates to 1 so you may use it easily in comparisons.
>>  */
>>  #define typecheck(type,x) \
>>  ({      type __dummy; \
>>        typeof(x) __dummy2; \
>>        (void)(&__dummy == &__dummy2); \
>>        1; \
>>  })
>>
>> #define typecheck_fn(type,function) \
>> ({      typeof(type) __tmp = function; \
>>       (void)__tmp; \
>> })
>>
>> Can anyone help me, explain the above code typecheck. How does
>> (void)(&__dummy == &__dummy2) evaluates to 1
>
> Infact I think it will never return 1, since the addresses of __dummy1
> and __dummy2 have to be different (off by 4 or 8). As pointed out it
> is the next line that always returns 1. The purpose of this line is to
> throw away warnings like "Incompatible pointer comparison" or
> something like that (haven't tried :-)) incase there is a mismatch.
>
> --
> Thanks -
> Manish
>



-- 
Regards,
Sri.

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

* Re: typecheck code
  2011-01-31 17:03 typecheck code Sri Ram Vemulpali
                   ` (3 preceding siblings ...)
  2011-01-31 18:03 ` Manish Katiyar
@ 2011-01-31 20:26 ` Dave Hylands
  2011-01-31 21:42   ` julie Sullivan
  4 siblings, 1 reply; 8+ messages in thread
From: Dave Hylands @ 2011-01-31 20:26 UTC (permalink / raw)
  To: Sri Ram Vemulpali; +Cc: Kernel-newbies, linux-kernel-mail

Hi Sri,

On Mon, Jan 31, 2011 at 9:03 AM, Sri Ram Vemulpali
<sri.ram.gmu06@gmail.com> wrote:
> Hi all,
>
> /*
>  * Check at compile time that something is of a particular type.
>  * Always evaluates to 1 so you may use it easily in comparisons.
>  */
>  #define typecheck(type,x) \
>  ({      type __dummy; \
>        typeof(x) __dummy2; \
>        (void)(&__dummy == &__dummy2); \
>        1; \
>  })
>
> #define typecheck_fn(type,function) \
> ({      typeof(type) __tmp = function; \
>       (void)__tmp; \
> })
>
> Can anyone help me, explain the above code typecheck. How does
> (void)(&__dummy == &__dummy2) evaluates to 1
>
> I appreciate any explain.

If dummy and dummy2 are of different types, then when you try and do a
pointer comparison (&dummy == &dummy2) it will produce a compiler
warning/error.

The actual comparison will always fail, but it doesn't matter since
the results aren't used.

typecheck always returns 1.

Dave Hylands

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

* Re: typecheck code
  2011-01-31 20:26 ` Dave Hylands
@ 2011-01-31 21:42   ` julie Sullivan
  0 siblings, 0 replies; 8+ messages in thread
From: julie Sullivan @ 2011-01-31 21:42 UTC (permalink / raw)
  To: Dave Hylands; +Cc: Sri Ram Vemulpali, Kernel-newbies, linux-kernel-mail

>If dummy and dummy2 are of different types, then when you try and do a
>pointer comparison (&dummy == &dummy2) it will produce a compiler
>warning/error.

O--ooohhh...
I came across this ages ago when I was trying to unravel the jiffies
wraparound macros and I've been scratching my head ever since trying
to figure out what this line _really_  did. A bit arcane, isn't it?
Thanks a lot Dave and everyone for explaining.

Cheers
Julie

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

end of thread, other threads:[~2011-01-31 21:42 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-31 17:03 typecheck code Sri Ram Vemulpali
2011-01-31 17:20 ` Jamie Iles
2011-01-31 17:22 ` Geert Uytterhoeven
2011-01-31 17:44 ` Rajat Sharma
2011-01-31 18:03 ` Manish Katiyar
2011-01-31 20:23   ` Sri Ram Vemulpali
2011-01-31 20:26 ` Dave Hylands
2011-01-31 21:42   ` julie Sullivan

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