linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH] 2.4.22pre10: {,un}likely_p() macros for pointers
@ 2003-08-05 12:44 Albert Cahalan
  2003-08-09  0:21 ` Jamie Lokier
  0 siblings, 1 reply; 13+ messages in thread
From: Albert Cahalan @ 2003-08-05 12:44 UTC (permalink / raw)
  To: linux-kernel mailing list, chip

Chip Salzenberg writes:

> GCC is warning about a pointer-to-int conversion when
> the likely() and unlikely() macros are used with pointer
> values.  So, for architectures where pointers are larger
> than 'int', I suggest this patch.
...
> -#define likely(x) __builtin_expect((x),1)
> -#define unlikely(x) __builtin_expect((x),0)
> +#define likely(x) __builtin_expect((x),      1)
> +#define likely_p(x) __builtin_expect((x) != 0, 1)
> +#define unlikely(x) __builtin_expect((x)      ,0)
> +#define unlikely_p(x) __builtin_expect((x) != 0 ,0)

That's ugly, plus the "_p" suffix is kind of a
standard for "predicate". (__builtin_constant_p, etc.)

I'm using these in the procps project:

// tell gcc what to expect:   if(unlikely(err)) die(err);
#define likely(x)       __builtin_expect(!!(x),1)
#define unlikely(x)     __builtin_expect(!!(x),0)
#define expected(x,y)   __builtin_expect((x),(y))

That makes a slight change to the meaning, since the
original value is no longer available. I've not
found that to be any trouble at all; if it is then
you could work around it using a statement-expression
with a variable, cast, and/or __typeof__.

Something like this:

#define likely(x) ({   \
__typeof__ (x) _tmp;    \
__builtin_expect(!!_tmp,1); \
_tmp; \
})



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

* Re: [PATCH] 2.4.22pre10: {,un}likely_p() macros for pointers
  2003-08-05 12:44 [PATCH] 2.4.22pre10: {,un}likely_p() macros for pointers Albert Cahalan
@ 2003-08-09  0:21 ` Jamie Lokier
  2003-08-09  8:13   ` Willy Tarreau
  0 siblings, 1 reply; 13+ messages in thread
From: Jamie Lokier @ 2003-08-09  0:21 UTC (permalink / raw)
  To: Albert Cahalan; +Cc: linux-kernel mailing list, chip

Albert Cahalan wrote:
> // tell gcc what to expect:   if(unlikely(err)) die(err);
> #define likely(x)       __builtin_expect(!!(x),1)
> #define unlikely(x)     __builtin_expect(!!(x),0)
> #define expected(x,y)   __builtin_expect((x),(y))

You may want to check that GCC generates the same code as for

	#define likely(x)	__builtin_expect((x),1)
	#define unlikely(x)	__builtin_expect((x),0)

I tried this once, and I don't recall the precise result but I do
recall it generating different code (i.e. not optimal for one of the
definitions).

-- Jamie

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

* Re: [PATCH] 2.4.22pre10: {,un}likely_p() macros for pointers
  2003-08-09  0:21 ` Jamie Lokier
@ 2003-08-09  8:13   ` Willy Tarreau
  2003-08-09  8:51     ` David S. Miller
  0 siblings, 1 reply; 13+ messages in thread
From: Willy Tarreau @ 2003-08-09  8:13 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: Albert Cahalan, linux-kernel mailing list, chip

On Sat, Aug 09, 2003 at 01:21:17AM +0100, Jamie Lokier wrote:
> Albert Cahalan wrote:
> > // tell gcc what to expect:   if(unlikely(err)) die(err);
> > #define likely(x)       __builtin_expect(!!(x),1)
> > #define unlikely(x)     __builtin_expect(!!(x),0)
> > #define expected(x,y)   __builtin_expect((x),(y))
> 
> You may want to check that GCC generates the same code as for
> 
> 	#define likely(x)	__builtin_expect((x),1)
> 	#define unlikely(x)	__builtin_expect((x),0)
> 
> I tried this once, and I don't recall the precise result but I do
> recall it generating different code (i.e. not optimal for one of the
> definitions).

anyway, in __builtin_expect(!!(x),0) there is a useless conversion, because
it's totally equivalent to __builtin_expect((x),0) (how could !!x be 0 if x
isn't ?), but I'm pretty sure that the compiler will add the test.

Willy


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

* Re: [PATCH] 2.4.22pre10: {,un}likely_p() macros for pointers
  2003-08-09  8:13   ` Willy Tarreau
@ 2003-08-09  8:51     ` David S. Miller
  2003-08-09  9:36       ` Jamie Lokier
                         ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: David S. Miller @ 2003-08-09  8:51 UTC (permalink / raw)
  To: Willy Tarreau; +Cc: jamie, albert, linux-kernel, chip

On Sat, 9 Aug 2003 10:13:46 +0200
Willy Tarreau <willy@w.ods.org> wrote:

> (how could !!x be 0 if x isn't ?)

I believe the C language allows for systems where the NULL pointer is
not zero.

I can't think of any reason why the NULL macro exists otherwise.

However, even if I'm right, I dread the guy who has to make other
people's code work on such a platform.  Using normal boolean tests for
NULL pointer checks is just too common.


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

* Re: [PATCH] 2.4.22pre10: {,un}likely_p() macros for pointers
  2003-08-09  8:51     ` David S. Miller
@ 2003-08-09  9:36       ` Jamie Lokier
  2003-08-09 10:10       ` Herbert Xu
  2003-08-09 10:42       ` Alan Cox
  2 siblings, 0 replies; 13+ messages in thread
From: Jamie Lokier @ 2003-08-09  9:36 UTC (permalink / raw)
  To: David S. Miller; +Cc: Willy Tarreau, albert, linux-kernel, chip

David S. Miller wrote:
> On Sat, 9 Aug 2003 10:13:46 +0200 Willy Tarreau <willy@w.ods.org> wrote:
> 
> > (how could !!x be 0 if x isn't ?)
> 
> I believe the C language allows for systems where the NULL pointer is
> not zero.

That is irrelevant.  The GCC manual says you can't use a pointer as
the argument to __builtin_expect anyway:

     Since you are limited to integral expressions for EXP, you should
     use constructions such as

          if (__builtin_expect (ptr != NULL, 1))
            error ();

     when testing pointer or floating-point values

-- Jamie

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

* Re: [PATCH] 2.4.22pre10: {,un}likely_p() macros for pointers
  2003-08-09  8:51     ` David S. Miller
  2003-08-09  9:36       ` Jamie Lokier
@ 2003-08-09 10:10       ` Herbert Xu
  2003-08-09 10:42       ` Alan Cox
  2 siblings, 0 replies; 13+ messages in thread
From: Herbert Xu @ 2003-08-09 10:10 UTC (permalink / raw)
  To: David S. Miller, linux-kernel

David S. Miller <davem@redhat.com> wrote:
> 
> I believe the C language allows for systems where the NULL pointer is
> not zero.

It does.  However it also says that whenever a pointer is compared
with the integer constant 0 it must be equal if and only if it is
a NULL pointer.

    An integer constant expression with the value 0, or such an expression
    cast to type void *, is called a null pointer constant.
-- 
Debian GNU/Linux 3.0 is out! ( http://www.debian.org/ )
Email:  Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* Re: [PATCH] 2.4.22pre10: {,un}likely_p() macros for pointers
  2003-08-09  8:51     ` David S. Miller
  2003-08-09  9:36       ` Jamie Lokier
  2003-08-09 10:10       ` Herbert Xu
@ 2003-08-09 10:42       ` Alan Cox
  2003-08-09 16:23         ` Jamie Lokier
  2 siblings, 1 reply; 13+ messages in thread
From: Alan Cox @ 2003-08-09 10:42 UTC (permalink / raw)
  To: David S. Miller
  Cc: Willy Tarreau, jamie, albert, Linux Kernel Mailing List, chip

On Sad, 2003-08-09 at 09:51, David S. Miller wrote:
> I believe the C language allows for systems where the NULL pointer is
> not zero.

Its a fudge for some systems. However NULL == 0 is always true.

> I can't think of any reason why the NULL macro exists otherwise.

<OldFart>
NULL is really important in K&R C because you don't have prototypes and
sizeof(foo *) may not be the same as sizeof(int). This leads to very
nasty problems that people nowdays forget about.
</OldFart>



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

* Re: [PATCH] 2.4.22pre10: {,un}likely_p() macros for pointers
  2003-08-09 10:42       ` Alan Cox
@ 2003-08-09 16:23         ` Jamie Lokier
  2003-08-09 17:30           ` NULL. Again. (was Re: [PATCH] 2.4.22pre10: {,un}likely_p()) Chip Salzenberg
  0 siblings, 1 reply; 13+ messages in thread
From: Jamie Lokier @ 2003-08-09 16:23 UTC (permalink / raw)
  To: Alan Cox
  Cc: David S. Miller, Willy Tarreau, albert, Linux Kernel Mailing List, chip

Alan Cox wrote:
> > I believe the C language allows for systems where the NULL pointer is
> > not zero.

The representation is not zero, however in the C language (since ANSI,
not sure about K&R), 0 is a valid name for the NULL pointer whatever
its representation.

> > I can't think of any reason why the NULL macro exists otherwise.
> 
> <OldFart>
> NULL is really important in K&R C because you don't have prototypes and
> sizeof(foo *) may not be the same as sizeof(int). This leads to very
> nasty problems that people nowdays forget about.
> </OldFart>

Not just K&R.  These are different because of varargs:

	printf ("%p", NULL);
	printf ("%p", 0);

-- Jamie

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

* NULL.  Again.  (was Re: [PATCH] 2.4.22pre10: {,un}likely_p())
  2003-08-09 16:23         ` Jamie Lokier
@ 2003-08-09 17:30           ` Chip Salzenberg
  2003-08-09 17:43             ` Sean Neakums
  2003-08-09 19:44             ` Jamie Lokier
  0 siblings, 2 replies; 13+ messages in thread
From: Chip Salzenberg @ 2003-08-09 17:30 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: Linux Kernel Mailing List

According to Jamie Lokier:
> Not just K&R.  These are different because of varargs:
> 	printf ("%p", NULL);
> 	printf ("%p", 0);

*SIGH*  I thought incorrect folk wisdom about NULL and zero and pointer
conversions had long since died out.  More fool I.  Please, *please*,
_no_one_else_ argue about NULL/zero/false etc. until after reading this:

  ===[[  http://www.eskimo.com/~scs/C-faq/s5.html  ]]===

I thank you, and linux users everywhere thank you.
-- 
Chip Salzenberg               - a.k.a. -               <chip@pobox.com>
"I wanted to play hopscotch with the impenetrable mystery of existence,
    but he stepped in a wormhole and had to go in early."  // MST3K

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

* Re: NULL.  Again.  (was Re: [PATCH] 2.4.22pre10: {,un}likely_p())
  2003-08-09 17:30           ` NULL. Again. (was Re: [PATCH] 2.4.22pre10: {,un}likely_p()) Chip Salzenberg
@ 2003-08-09 17:43             ` Sean Neakums
  2003-08-11  1:04               ` Jamie Lokier
  2003-08-11 23:06               ` Timothy Miller
  2003-08-09 19:44             ` Jamie Lokier
  1 sibling, 2 replies; 13+ messages in thread
From: Sean Neakums @ 2003-08-09 17:43 UTC (permalink / raw)
  To: linux-kernel

Chip Salzenberg <chip@pobox.com> writes:

> According to Jamie Lokier:
>> Not just K&R.  These are different because of varargs:
>> 	printf ("%p", NULL);
>> 	printf ("%p", 0);
>
> *SIGH*  I thought incorrect folk wisdom about NULL and zero and pointer
> conversions had long since died out.  More fool I.  Please, *please*,
> _no_one_else_ argue about NULL/zero/false etc. until after reading this:
>
>   ===[[  http://www.eskimo.com/~scs/C-faq/s5.html  ]]===
>
> I thank you, and linux users everywhere thank you.

I had thought that the need for writing NULL where a pointer is
expected in varags functions was because the machine may have
different sizes for pointers and int.  In the case of the second
printf call above, if pointers are 64-bit and integers are 32-bit,
printf will read eight bytes from the stack, and only four will have
been occupied by the integer 0.


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

* Re: NULL.  Again.  (was Re: [PATCH] 2.4.22pre10: {,un}likely_p())
  2003-08-09 17:30           ` NULL. Again. (was Re: [PATCH] 2.4.22pre10: {,un}likely_p()) Chip Salzenberg
  2003-08-09 17:43             ` Sean Neakums
@ 2003-08-09 19:44             ` Jamie Lokier
  1 sibling, 0 replies; 13+ messages in thread
From: Jamie Lokier @ 2003-08-09 19:44 UTC (permalink / raw)
  To: Chip Salzenberg; +Cc: Linux Kernel Mailing List

Chip Salzenberg wrote:
> According to Jamie Lokier:
> > Not just K&R.  These are different because of varargs:
> > 	printf ("%p", NULL);
> > 	printf ("%p", 0);
> 
> *SIGH*  I thought incorrect folk wisdom about NULL and zero and pointer
> conversions had long since died out.  More fool I.  Please, *please*,
> _no_one_else_ argue about NULL/zero/false etc. until after reading this:
> 
>   ===[[  http://www.eskimo.com/~scs/C-faq/s5.html  ]]===

Thanks Chip; I am much enlightened.  That is a fine URL.

To onlookers: neither of those printf statements is portable :)

-- Jamie


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

* Re: NULL.  Again.  (was Re: [PATCH] 2.4.22pre10: {,un}likely_p())
  2003-08-09 17:43             ` Sean Neakums
@ 2003-08-11  1:04               ` Jamie Lokier
  2003-08-11 23:06               ` Timothy Miller
  1 sibling, 0 replies; 13+ messages in thread
From: Jamie Lokier @ 2003-08-11  1:04 UTC (permalink / raw)
  To: linux-kernel

Sean Neakums wrote:
> I had thought that the need for writing NULL where a pointer is
> expected in varags functions was because the machine may have
> different sizes for pointers and int.  In the case of the second
> printf call above, if pointers are 64-bit and integers are 32-bit,
> printf will read eight bytes from the stack, and only four will have
> been occupied by the integer 0.

It is incorrect to write NULL as a varargs argument.  It won't
necessarily pass a pointer because:

   1. a valid definition of NULL is "0".

If you want to pass a pointer to varargs, you might have considered
writing "(void *) 0", but that doesn't work because:

   2. a machine may have different sizes for different pointer types.

You must write "(type) 0" or "(type) NULL", using the correct pointer type.

-- Jamie

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

* Re: NULL.  Again.  (was Re: [PATCH] 2.4.22pre10: {,un}likely_p())
  2003-08-09 17:43             ` Sean Neakums
  2003-08-11  1:04               ` Jamie Lokier
@ 2003-08-11 23:06               ` Timothy Miller
  1 sibling, 0 replies; 13+ messages in thread
From: Timothy Miller @ 2003-08-11 23:06 UTC (permalink / raw)
  To: Sean Neakums; +Cc: linux-kernel



Sean Neakums wrote:
> Chip Salzenberg <chip@pobox.com> writes:
> 
> 
>>According to Jamie Lokier:
>>
>>>Not just K&R.  These are different because of varargs:
>>>	printf ("%p", NULL);
>>>	printf ("%p", 0);
>>
>>*SIGH*  I thought incorrect folk wisdom about NULL and zero and pointer
>>conversions had long since died out.  More fool I.  Please, *please*,
>>_no_one_else_ argue about NULL/zero/false etc. until after reading this:
>>
>>  ===[[  http://www.eskimo.com/~scs/C-faq/s5.html  ]]===
>>
>>I thank you, and linux users everywhere thank you.
> 
> 
> I had thought that the need for writing NULL where a pointer is
> expected in varags functions was because the machine may have
> different sizes for pointers and int.  In the case of the second
> printf call above, if pointers are 64-bit and integers are 32-bit,
> printf will read eight bytes from the stack, and only four will have
> been occupied by the integer 0.
> 

Yes, but you're leaving information out.  If you read the FAQ, you'll 
find that NULL would not be the right thing to use in some cases.  For 
instance, (char *)0 may be a different value from (void *)0, so it's 
best to cast the pointer when passing to printf or something which uses 
varargs.



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

end of thread, other threads:[~2003-08-11 22:52 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-08-05 12:44 [PATCH] 2.4.22pre10: {,un}likely_p() macros for pointers Albert Cahalan
2003-08-09  0:21 ` Jamie Lokier
2003-08-09  8:13   ` Willy Tarreau
2003-08-09  8:51     ` David S. Miller
2003-08-09  9:36       ` Jamie Lokier
2003-08-09 10:10       ` Herbert Xu
2003-08-09 10:42       ` Alan Cox
2003-08-09 16:23         ` Jamie Lokier
2003-08-09 17:30           ` NULL. Again. (was Re: [PATCH] 2.4.22pre10: {,un}likely_p()) Chip Salzenberg
2003-08-09 17:43             ` Sean Neakums
2003-08-11  1:04               ` Jamie Lokier
2003-08-11 23:06               ` Timothy Miller
2003-08-09 19:44             ` Jamie Lokier

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