linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [IDEA+RFC] Possible solution for min()/max() war
@ 2001-08-30 20:44 Herbert Rosmanith
  2001-08-30 21:06 ` Peter T. Breuer
  2001-08-30 21:17 ` Richard B. Johnson
  0 siblings, 2 replies; 158+ messages in thread
From: Herbert Rosmanith @ 2001-08-30 20:44 UTC (permalink / raw)
  To: linux-kernel; +Cc: ptb


>   if sizeof(typeof(a)) != sizeof(typeof(b))
>       BUG() // sizes differ

this is not neccessarily a problem. should work with char/short char/int
short/int comparison.

only problem seems to be signed/unsigned int comparison.

>   const (typeof(a)) _a = ~(typeof(a))0
>   const (typeof(b)) _b = ~(typeof(b))0
>   if _a < 0 && _b > 0 || _a > 0 && b < 0
>       BUG() // one signed, the other unsigned
>   standard_max(a,b)

if sizeof(typeof(a))==sizeof(int) && sizeof(typeof(b))==sizeof(int) &&
   ( _a < 0 && _b > 0 || _a > 0 && b < 0 )
	BUG() // signed unsigned int compare


^ permalink raw reply	[flat|nested] 158+ messages in thread
[parent not found: <m2bskndlkt.fsf@sympatico.ca>]
* Re: [IDEA+RFC] Possible solution for min()/max() war
@ 2001-09-06  1:51 Rick Hohensee
  2001-09-06 10:12 ` VDA
  0 siblings, 1 reply; 158+ messages in thread
From: Rick Hohensee @ 2001-09-06  1:51 UTC (permalink / raw)
  To: linux-kernel


>VDA
>#define min2(a,b) ({ \
>    typeof(a) __a = (a); \
>    typeof(b) __b = (b); \
>    if( sizeof(a) != sizeof(b) ) BUG(); \
>    if( ~(typeof(a))0 > 0 && ~(typeof(b))0 < 0) BUG(); \
>    if( ~(typeof(a))0 < 0 && ~(typeof(b))0 > 0) BUG(); \
>    (__a < __b) ? __a : __b; \
>    })
>
>#define min3(type,a,b) ({ \
>    type __a = (a); \
>    type __b = (b); \
>    if( sizeof(a) > sizeof(type) ) BUG(); \
>    if( sizeof(b) > sizeof(type) ) BUG(); \
>    (__a < __b) ? __a : __b; \
>    })
>


DesJardin's argument is finely crafted, but does this support it? Is min3
intended to be what Linus was talking about? I usually use m4 when I need
conditionals in macros, and I don't use C conditional statements much, but
isn't what Linus was saying simply something like...


#define min(type,a,b)		(type) a < (type) b ? (type) a : (type) b ;


Looking at the trade-offs should account for the simplicity. Even if my
code is wrong, it's about reflective of the required complexity, y/n?
The simple form doesn't catch things. That's OK for a default. Maybe
that's what you want. If it's simple you know what you have, regardless. 
"programmer error" is frequently a sign of compiler mis-design.

One reason I'm speaking in support of Linus on this one is that there's
something oddly Forth-like to a simple min(type,a,b). No coder nowhere
knows simplicity like Chuck Moore. Linux is ripe for a bit of that. The
other thing about the 3-arg min thing is that it's rather original, and it
amuses me to see Linus get disrespected for a quantum of real creativity
in his own forum. Linux is also ripe for a bit of free thinking. What's
open source for if all it helps is closed minds?

Rick Hohensee
                www.
                           cLIeNUX
                                          .com
                                                        humbubba@smart.net

^ permalink raw reply	[flat|nested] 158+ messages in thread
* Re: [IDEA+RFC] Possible solution for min()/max() war
@ 2001-09-04 13:17 Petr Vandrovec
  0 siblings, 0 replies; 158+ messages in thread
From: Petr Vandrovec @ 2001-09-04 13:17 UTC (permalink / raw)
  To: VDA; +Cc: linux-kernel

On  4 Sep 01 at 12:09, VDA wrote:
> min2 performs a very strict checking.
> min3 gives you full control, but checks for too small target type.
> Do anybody see any flaws? Any improvements?
> For compiler folks: Why GCC compiles ...f(1);f(1);f(1)... to
> ...
>         pushl $1
>         call f
>         addl $32,%esp  <-- My grandma optimizes better
>         addl $-12,%esp <-- ?
>         pushl $1
>         call f
>         addl $16,%esp  <-- ?
>         addl $-12,%esp <-- ?

Compile with 'gcc -mpreferred-stack-boundary=2', gcc generates
unbelievable stupid code for other values.
                                        Best regards,
                                            Petr Vandrovec
                                            vandrove@vc.cvut.cz
                                            

^ permalink raw reply	[flat|nested] 158+ messages in thread
* Re: [IDEA+RFC] Possible solution for min()/max() war
@ 2001-09-04  9:09 VDA
  0 siblings, 0 replies; 158+ messages in thread
From: VDA @ 2001-09-04  9:09 UTC (permalink / raw)
  To: linux-kernel

A test program.
min2 performs a very strict checking.
min3 gives you full control, but checks for too small target type.
Do anybody see any flaws? Any improvements?
For compiler folks: Why GCC compiles ...f(1);f(1);f(1)... to
...
        pushl $1
        call f
        addl $32,%esp  <-- My grandma optimizes better
        addl $-12,%esp <-- ?
        pushl $1
        call f
        addl $16,%esp  <-- ?
        addl $-12,%esp <-- ?
...
--------------------------------------------------------------------
#include <stdio.h>

#define min2(a,b) ({ \
    typeof(a) __a = (a); \
    typeof(b) __b = (b); \
    if( sizeof(a) != sizeof(b) ) BUG(); \
    if( ~(typeof(a))0 > 0 && ~(typeof(b))0 < 0) BUG(); \
    if( ~(typeof(a))0 < 0 && ~(typeof(b))0 > 0) BUG(); \
    (__a < __b) ? __a : __b; \
    })

#define min3(type,a,b) ({ \
    type __a = (a); \
    type __b = (b); \
    if( sizeof(a) > sizeof(type) ) BUG(); \
    if( sizeof(b) > sizeof(type) ) BUG(); \
    (__a < __b) ? __a : __b; \
    })

#define BUG() printf("BUG at %i\n",__LINE__)
#define llong long long

// Uncomment {} for compile, comment for gcc -S -O2 optimizer test
void f(int v);
// void f(int v) {}

int main() {
    signed char  sc=1; unsigned char  uc=1;
    signed short ss=1; unsigned short us=1;
    signed int   si=1; unsigned int   ui=1;
    signed long  sl=1; unsigned long  ul=1;
    signed llong su=1; unsigned llong uu=1;

    f(min2(sc,sc)); // not a BUG
    f(min2(sc,uc)); // not a BUG: (typeof(x))0 first expanded to signed int
    f(1); // optimizer test: all the mins must be optimized to 
    f(1); // f(1) so do gcc -S -O2 and inspect .s file
    f(min2(ss,ss)); // not a BUG
    f(min2(ss,us)); // not a BUG: (typeof(x))0 first expanded to signed int
    f(min2(si,si)); // not a BUG
    f(min2(si,ui)); // BUG: signedness mismatch
    f(min2(sl,sl)); // not a BUG
    f(min2(sl,ul)); // BUG: signedness mismatch
    f(min2(su,su)); // not a BUG
    f(min2(su,uu)); // BUG: signedness mismatch
    f(min2(sc,ss)); // BUG: size mismatch
    f(min3(unsigned char, sc,uc)); // not a BUG
    f(min3(int,           sc,ss)); // not a BUG
    f(min3(unsigned llong,ss,uu)); // not a BUG
    f(min3(unsigned long, ss,uu)); // BUG: target type is too small
    
    return 0;
}
-------------------------------------------------------------
Best regards, VDA
mailto:VDA@port.imtp.ilyichevsk.odessa.ua
http://port.imtp.ilyichevsk.odessa.ua/vda/



^ permalink raw reply	[flat|nested] 158+ messages in thread
* Re: [IDEA+RFC] Possible solution for min()/max() war
@ 2001-09-03 23:16 David desJardins
  0 siblings, 0 replies; 158+ messages in thread
From: David desJardins @ 2001-09-03 23:16 UTC (permalink / raw)
  To: linux-kernel

Linus Torvalds <torvalds@transmeta.com> writes:
> For example, let's look at this perfectly natural code:
> 
> static int unix_mkname(struct sockaddr_un * sunaddr, int len, unsigned
> *hashp)
> {
> if (len <= sizeof(short) || len > sizeof(*sunaddr))
> return -EINVAL;
> ...

> code that is totally correct, and that it would make _no_ sense in
> writing any other way.

The code is correct, but if one is adding explicit types, for clarity
and to avoid introducing bugs, then I think that code like this is
exactly where they most belong:

  if ((size_t) len <= sizeof(short) || (size_t) len > sizeof(*sunaddr))

If that prevents one person from later writing buggy code like:

  if ((size_t) len <= sizeof(short))

then it's a Good Thing.

  -- David desJardins

^ permalink raw reply	[flat|nested] 158+ messages in thread
* Re: [IDEA+RFC] Possible solution for min()/max() war
@ 2001-09-03 20:35 David desJardins
  2001-09-04  8:08 ` VDA
  0 siblings, 1 reply; 158+ messages in thread
From: David desJardins @ 2001-09-03 20:35 UTC (permalink / raw)
  To: linux-kernel

Linus Torvalds <torvalds@transmeta.com> writes:
> I have one thing to say to people who do not like the new min/max 
> functions: most of them probably never even _understood_ the multitude 
> of bugs that are inherent in the classical 
> 
>         #define min(x,y) ((x) < (y) ? (x) : (y)) 

I think you're mistaken about what people understand.

The explicit typing of MIN and MAX will avoid some bugs that have to do
with the comparison of entities of different types.  The explicit typing
will also introduce some bugs, when a user uses the wrong type (e.g.,
when the code is initially written with the correct type, but then
someone later changes the type of the variables, and doesn't remember to
change the type in the macro call).  Overall, I think it will be about a
wash.

If this is really a serious problem, then people shouldn't be using the
comparison operators like "<" either, as they have exactly the same
problem when used to compare objects of different types (particularly
since C has such broken rules for deciding what type to use when
comparing objects of different types).  Instead, we should have
LESSTHAN(type,a,b), etc.

I think the best approach to bug avoidance would be two-argument MIN and
MAX functions which require that both arguments have the same type, but
where that can be any type.  Then users who want to compare objects of
different types would have to explicitly cast one to the type of the
other (or both to a third common type).  In the most common case where
users are simply comparing objects of the same type, there would be no
need or reason to change the code.

It's simple enough for an external checker to confirm that this rule is
followed.  The same checker could enforce the same rule for "<" and
other comparison operators, which would probably help eliminate several
bugs (without the unacceptably clunky LESSTHAN macro).

I think no one who is comparing objects of two different types can
legitimately complain about being asked to cast one (or both) of them to
a common type: the user, rather than the compiler, should indeed choose
the type of the comparison.  But that's different from redundantly
adding the type everywhere to comparisons of objects of the same type,
which introduces, rather than eliminating, a source of error.

  -- David desJardins

^ permalink raw reply	[flat|nested] 158+ messages in thread
[parent not found: <fa.eeq0k8v.1v28iaa@ifi.uio.no>]
* Re: [IDEA+RFC] Possible solution for min()/max() war
@ 2001-08-31 18:29 Andy Chou
  2001-08-31 18:52 ` Roman Zippel
  0 siblings, 1 reply; 158+ messages in thread
From: Andy Chou @ 2001-08-31 18:29 UTC (permalink / raw)
  To: Roman Zippel; +Cc: ptb, linux-kernel

SVC isn't the "Stanford Checker" that has been resulting in kernel
patches.  The name "Stanford Checker" was invented by people on LKML; the
real name of the project is Meta-level compilation, and its URL is:

http://hands.stanford.edu

SVC isn't a model checker either.  It's an implementation of cooperating
decision procedures.

-Andy


> > Stanford checker? Is that a programmable C type checker? If so, lemmee
> > at it. Have you a URL, btw?

> http://verify.stanford.edu/SVC/
> You should search the archive to look for some good examples, how it can
> help.


^ permalink raw reply	[flat|nested] 158+ messages in thread
* Re: [IDEA+RFC] Possible solution for min()/max() war
@ 2001-08-31 18:24 Herbert Rosmanith
  0 siblings, 0 replies; 158+ messages in thread
From: Herbert Rosmanith @ 2001-08-31 18:24 UTC (permalink / raw)
  To: linux-kernel


From: Rik van Riel <riel@conectiva.com.br>
> On Fri, 31 Aug 2001, Herbert Rosmanith wrote:
> > "I contemplated about the way of Linus, and eventually I begin to
> > understand HIS aim."
> 
> Understanding his aim is useful. It allows you to get
> out of the way when he starts shooting.

Ah, eventually I begin to understand why Linus is exercising in
pistols with ESR.

> > excuse me. this is ridiculous.
> 
> Well, we knew that before the thread started. Can't win
> a holy war.

what I wanted to say is: it should not neccessary to <peter breuer>
"seeing this discussion fly past for a week I begin to
 understand what Linus' aim might be"
</peter breuer>

spend a week reading lkml and maybe catch a hint about what Linus
had in mind when introducing some code.


^ permalink raw reply	[flat|nested] 158+ messages in thread
* Re: [IDEA+RFC] Possible solution for min()/max() war
@ 2001-08-31 18:13 Herbert Rosmanith
  0 siblings, 0 replies; 158+ messages in thread
From: Herbert Rosmanith @ 2001-08-31 18:13 UTC (permalink / raw)
  To: linux-kernel


From: "Peter T. Breuer" <ptb@it.uc3m.es>
> > From: "Herbert Rosmanith" <herp@wildsau.idv.uni-linz.ac.at>
> >
> > if sizeof(typeof(a))==sizeof(int) && sizeof(typeof(b))==sizeof(int) &&
> >    ( _a < 0 && _b > 0 || _a > 0 && b < 0 )
> >       BUG() // signed unsigned int compare
> 
> What makes sizeof(int) so magic?

ask your compiler.

> Are you saying that the problems don't arise between signed long long
> and unsigned long long?

no.

> I saw an example that seemed generic for all signed unsigned
> comparisons, namely that signed int and unsigned int are compared as
> unsigned, so (unsigned)2 < (signed)-1. 

which is wrong. so?

> Are you saying that signed long and unsigned long are NOT compared as
> unsigned iff sizeof(long) != sizeof(int).  Woooo!  Who wrote the C spec?
> No kidding? There is a special clause for comparisons that use the
> native machine word?

excuse me, pete, but being sarcastic does not suite you well:

in Message-Id: <200108311322.PAA12269@nbd.it.uc3m.es>
you write:
> #define MIN(x,y) ({\
>    const typeof(x) _x = ~(typeof(x))0; \
>    const typeof(y) _y = ~(typeof(y))0; \
>    if (sizeof(_x) != sizeof(_y)) \
>      MINMAX_BUG; \


this is just not right. you don't  even honour if x and y are of the
same signedness! if x and y are of the same signedness, a comparison
can be done at absolutely no risk regardless of the size!

and even *if* the sizes differ, there are cases, where the comparison
still can be done at no risk. namely:

 signed short / unsigned char       ->  OK
 unsigned short / signed char       ->  OK
 signed int / unsigned char         ->  OK
 signed int / unsigned short        ->  OK
 signed long long / unsigned char   ->  OK
 signed long long / unsigned short  ->  OK

(I don't know about signed long long / unsigned int, I'd have to ask the
compiler/assembler. but I guess it will be okay, too)

but:

  unsigned int / signed char        -> fails.
  unsigned int / signed short       -> fails.
  unsigned long long / signed char  -> fails.
  unsigned long long / signed short -> fails.
  unsigned long long / signed int   -> fails.

I haven't really verified all cases, they are a conclusion from seeing
the code gcc generates.

if we follow your minmax-macro code:

>    if ((_x > (typeof(x))0 && _y < (typeof(y))0) \
>    ||  (_x < (typeof(x))0 && _y > (typeof(y))0)) \
>      MINMAX_BUG; \
>    __MIN(x,y); \
>  })

if I see this right, after requiring the size be the same, you also
require the same signdness?

but:

 : 	char a; unsigned char b;
 : 
 : 	a=-1;	b=255;
 : 	if (a<b) ....

will work perfectly. same applies for short a/unsigned short b;





^ permalink raw reply	[flat|nested] 158+ messages in thread
* Re: [IDEA+RFC] Possible solution for min()/max() war
@ 2001-08-31 17:41 Herbert Rosmanith
  2001-08-31 17:57 ` Rik van Riel
  0 siblings, 1 reply; 158+ messages in thread
From: Herbert Rosmanith @ 2001-08-31 17:41 UTC (permalink / raw)
  To: linux-kernel


From: "Peter T. Breuer" <ptb@it.uc3m.es>
> And after seeing this discussion fly past for a week I begin to
> understand what Linus' aim might be.

haha. 
"I contemplated about the way of Linus, and eventually I begin to
understand HIS aim."

excuse me. this is ridiculous.



^ permalink raw reply	[flat|nested] 158+ messages in thread
[parent not found: <fa.ehba65v.10i6abc@ifi.uio.no>]
* Re: [IDEA+RFC] Possible solution for min()/max() war
@ 2001-08-31 14:28 Herbert Rosmanith
  2001-08-31 14:37 ` Herbert Rosmanith
  0 siblings, 1 reply; 158+ messages in thread
From: Herbert Rosmanith @ 2001-08-31 14:28 UTC (permalink / raw)
  To: ptb; +Cc: zippel, ptb, patl, linux-kernel


> "A month of sundays ago Roman Zippel wrote:"
> > On Fri, 31 Aug 2001, Peter T. Breuer wrote:
> >
> > >    if (sizeof(_x) != sizeof(_y)) \
> > >      MIN_BUG(); \
> >
> > What bug are you trying to fix here?
>
> Wake up!

good morning, peter.

try comparing e.g. unsigned char with signed short.

roman is right if he asks "What bug are you trying to fix here?" sure,
sometimes there is a bug, sometimes there is not. so with the question
"*what* bug" roman surely means, which situation do you want to identify
as the buggy one?

if all you do is to compare the size of the operands without taking
into account the architectural limit, you will also mock about
different-sized comparison which are perfectly legal and not buggy
at all.

look at this code:

  : #include        <stdio.h>
  : 
  : int main() {
  : unsigned short us;
  : signed char sc;
  : 
  :         us=65535;
  :         sc=-2;
  :         if (us>sc) printf("us>sc %d %d\n",us,sc);
  : 
  :         return 0;
  : }

which compiles to:

  :      movw $65535,-2(%ebp)
  :      movb $-2,-3(%ebp)
  :      xorl %eax,%eax
  :      movw -2(%ebp),%ax
  :      movsbl -3(%ebp),%edx
  :      cmpl %edx,%eax
  :      jle .L3

you see this? short and char get expanded to 32bit int (I have a x86),
and a signed comparison can be done without danger. "jle" jumps if
SF != OF, which accounts to "op1 < op2" in a signed compare. the
"unsigned short" quantum gets expanded to an "unsigned int", which
is no problem, since the bit16-31 will be 0. the "signed char" will
also be expanded to 32bit and eventually (for negative values) have
bit31-bit8 "1". thus, a signed compare with 32bits will work perfectly
well for an unsiged 16bit value.

The problem arises when one of the variables cannot be expanded any
more. Of course, the compiler could generate code to i.e. expand
int32 to long long, but this has not be done, may be or may not be
done in a future release or whatever.

For instance:

  : int main() {
  : unsigned int ui;
  : signed char sc;
  : 
  :         ui=1;
  :         sc=-2;
  :         if (ui>sc) printf("ui>sc %d %d\n",ui,sc);
  : 
  :         return 0;
  : }

will not work as expected.

the reason is that:

  :         movl $1,-4(%ebp)
  :         movb $-2,-5(%ebp)
  :         movsbl -5(%ebp),%eax
  :         cmpl %eax,-4(%ebp)
  :         jbe .L3

"jbe" honours CF and ZF, which accounts to an *unsigned* compare.
however, the negative "signed char" got expanded to 0xffffffff,
which is, in an unsigned compare-context, greater than 0x00000001.

I hope I've shown that "sizeof(a) != sizeof(b)" is not neccessarily
*always* a buggy situation.

Even with int, a "signed int" with an "unsigned char" compare could
be done. The buggy situation is when the bigger variable is unsigned,
in size equal to the architectural limit, and the smaller variable
is signed.

I hope I got that right.

cheers,
herp
 






^ permalink raw reply	[flat|nested] 158+ messages in thread
* Re: [IDEA+RFC] Possible solution for min()/max() war
@ 2001-08-31 14:28 Martin Knoblauch
  0 siblings, 0 replies; 158+ messages in thread
From: Martin Knoblauch @ 2001-08-31 14:28 UTC (permalink / raw)
  To: linux-kernel; +Cc: torvalds

> Re: [IDEA+RFC] Possible solution for min()/max() war
> 
> From: Linus Torvalds (torvalds@transmeta.com)
> Date: Mon Aug 27 2001 - 23:59:41 EST
> 
> 
> There were a few alternatives that we looked at (or rather, David
> implemented, and I ended up rejecting due to various reasons), but they
> all boiled down to "how do we sanely generate min/max functions while at
> the same time forcing people to understand the types in question". Some
> of the intermediate patches had the type in the macro name, ie things
> like "min_uint()" and "min_slong()". The final version (ie the one in
> 2.4.9) was deemed to be the most flexible.
> 

 Reading the whole (entertaining) thread my question is: couldn't the
min/max change wait until 2.5? It seems to "break" some code and that
should not happen in a "stable" stream?

Martin
-- 
------------------------------------------------------------------
Martin Knoblauch         |    email:  Martin.Knoblauch@TeraPort.de
TeraPort GmbH            |    Phone:  +49-89-510857-309
C+ITS                    |    Fax:    +49-89-510857-111
http://www.teraport.de   |    Mobile: +49-170-4904759

^ permalink raw reply	[flat|nested] 158+ messages in thread
* Re: [IDEA+RFC] Possible solution for min()/max() war
@ 2001-08-31  2:48 Rick Hohensee
  0 siblings, 0 replies; 158+ messages in thread
From: Rick Hohensee @ 2001-08-31  2:48 UTC (permalink / raw)
  To: linux-kernel

Linus' 3-arger is the way to go for mix/max defaults. Very simple,
particularly in terms of obscure features required.  Why you guys always
want to be at the nether reaches of the .info's is beyond me. 

Rick Hohensee
                www.
                           cLIeNUX
                                          .com
                                                        humbubba@smart.net


^ permalink raw reply	[flat|nested] 158+ messages in thread
* Re: [IDEA+RFC] Possible solution for min()/max() war
@ 2001-08-31  2:34 Andy Chou
  0 siblings, 0 replies; 158+ messages in thread
From: Andy Chou @ 2001-08-31  2:34 UTC (permalink / raw)
  To: Peter T. Breuer; +Cc: linux-kernel

How about:

#define AssertNow(x) switch(1) { case (x): case 0: }

as in:

AssertNow(sizeof(typeof(x)) == sizeof(typeof(y)));

I'm not sure if gcc optimizes this away, but it would be easy for someone
to find out.

I didn't invent this.

-Andy


> And I was hoping that somebody could produce some gcc magic
> replacement for BUG() that means "don't compile me". Perhaps
> a bit of illegal assembler code with a line reference in?
> Surely gcc must have something like __builtin_wont_compile()?
> It just needs to be a leaf of the RTL that evokes a compile error.


^ permalink raw reply	[flat|nested] 158+ messages in thread
[parent not found: <20010830174227.A10673@furble>]
[parent not found: <791753058.999219857@[169.254.198.40]>]
* Re: [IDEA+RFC] Possible solution for min()/max() war
@ 2001-08-30 20:35 Herbert Rosmanith
  0 siblings, 0 replies; 158+ messages in thread
From: Herbert Rosmanith @ 2001-08-30 20:35 UTC (permalink / raw)
  To: linux-kernel



hi,

I just can't see why the new min/max macros are any better than the old
one.

given the following two variables: "signed int i" and "unsigned int j"
assume i=-1 and j=2. we all know that -1 < 2, unfortunately, C doesnt
know that, probably when these values are stored in machineword quantities.
(i.e. no problem wich char and short, but with int on 32bit platform).

now, the new macros come in. we could now either write:

    min(unsigned int,i,j)           ; case 1
or
    min(signed int,i,j)             ; case 2


when casting to unsigned int, -1 will become 0xffffffff and 
"min(unsigned int,-1,2)" will return 2. this is wrong.

case 2 will give the right result.

but what will happen if the unsigned variable is so large that it will
use the most significant bit?

assume i=-1 and j=0xfffffff0;
still, -1 < 0xfffffff0 is true.

	min(unsigned int,i,j)
will give 0xfffffff0 because its < 0xffffffff;
wrong result.

	min(signed int,i,j)
will give 0xfffffff0 because it will be cast to -16 which is < -1.
wrong result again.

I think this shows that the type-argument in the macros gain nothing.
Instead, whenever we encounter such a problem, the code should be
closely investigated.

I think that this really is some compiler-issue. signed/unsigned comparison
is okay for char and short, but not for int; looks like the compiler
forgets to set or evaluate the carry-flag, perhaps?


^ permalink raw reply	[flat|nested] 158+ messages in thread
* Re: [IDEA+RFC] Possible solution for min()/max() war
@ 2001-08-30 17:32 mike_phillips
  2001-08-30 17:45 ` Ion Badulescu
  0 siblings, 1 reply; 158+ messages in thread
From: mike_phillips @ 2001-08-30 17:32 UTC (permalink / raw)
  To: Ion Badulescu; +Cc: linux-kernel

> So I have this number, -200, which is stored in an int. I have this 
other
> number, 200, which is stored in an unsigned char. Everybody in his right
> mind will agree that -200 is smaller than 200, the compiler will do just
> that, yet you disagree???

Now try doing that with an int and an unsigned int, you'll get 200, not 
-200.

Mike



^ permalink raw reply	[flat|nested] 158+ messages in thread
* Re: [IDEA+RFC] Possible solution for min()/max() war
@ 2001-08-30  9:56 Herbert Rosmanith
  2001-08-30 13:09 ` Helge Hafting
  0 siblings, 1 reply; 158+ messages in thread
From: Herbert Rosmanith @ 2001-08-30  9:56 UTC (permalink / raw)
  To: linux-kernel


> Please guys. The issue of sign in comparisons are a LOT more complicated
> than most of you seem to think.

as a friend of mine put it on IRC:
  "Your little brains are not able to grasp the complicated issue of
  sign in comparisons."

If the problem is compiler-related, shouldn't it be forwared to the
gcc-group?

e.g.:

    : void foo() {
    : unsigned int i;
    : signed int j;
    : 
    : 	i=j;
    : }

does not generated a warning even with "-Wall". I think it should print
out something like "warning: sign will be lost in signed to unsigned
assignment".

The rules for signed/unsigned comparison should be:
 o the sign is always "sticky" (i.e. signed/unsigned -> signed)
 o data size is expanded to the size of the larger var.
 o (1) if the larger var is unsigned, data size is expanded
       even further.
   (2) if that's not possible, use carry flag.

However, I noticed that this "value-preserving arithmetic conversion"
is not always performed.

code follows:


    : #include        <stdio.h>
    : 
    : int main() {
    : 
    : unsigned char ca;
    : signed char cb;
    : 
    : unsigned short sa;
    : signed short sb;
    : 
    : unsigned int ia;
    : signed int ib;
    : 
    :         ca=0xff;
    :         cb=0xff;
    :         printf("ca=%u cb=%d\n",ca,cb);
    :         if (ca<cb) printf("ca<cb\n");
    :         else if (ca>cb) printf("ca>cb\n");
    :         else printf("ca==cb\n");
    : 
    :         sa=0xffff;
    :         sb=0xffff;
    :         printf("sa=%u sb=%hd\n",sa,sb);
    :         if (sa<sb) printf("sa<sb\n");
    :         else if (sa>sb) printf("sa>sb\n");
    :         else printf("sa==sb\n");
    : 
    :         ia=0xffffffff;
    :         ib=0xffffffff;
    :         printf("ia=%u ib=%d\n",ia,ib);
    :         if (ia<ib) printf("ia<ib\n");
    :         else if (ia>ib) printf("ia>ib\n");
    :         else printf("ia==ib\n");
    : 
    :         return 0;
    : }

will result to:

    : bash-2.03# cc -Wsign-compare -o cm cm.c
    : cm.c: In function `main':
    : cm.c:32: warning: comparison between signed and unsigned
    : cm.c:33: warning: comparison between signed and unsigned
    : bash-2.03# ./cm
    : ca=255 cb=-1
    : ca>cb
    : sa=65535 sb=-1
    : sa>sb
    : ia=4294967295 ib=-1
    : ia==ib


so, in the "int" case, the result of the comparison is wrong. (shouldnt
it be expanded to long long, or at least use the carry-flag?)
If the min/max macros explicitly cast a signed data-type to an
unsigned one, the meaning of the sign-bit will be lost in any
way, not only in the int-case.




^ permalink raw reply	[flat|nested] 158+ messages in thread
[parent not found: <200108291905.f7TJ59T11456@wildsau.idv-edu.uni-linz.ac.at>]
* Re: [IDEA+RFC] Possible solution for min()/max() war
@ 2001-08-29  1:33 Ignacio Vazquez-Abrams
  0 siblings, 0 replies; 158+ messages in thread
From: Ignacio Vazquez-Abrams @ 2001-08-29  1:33 UTC (permalink / raw)
  To: linux-kernel

What if:

1) We rename the new min() as type_min(),
2) We bring back the old min(), and
      HERE is the _important_ part:
3) Have min() bitch and moan real loud whenever the two arguments
       aren't of the same type.

That way we can have it both ways: a min() that is easy and convenient, and a
min() that can handle two arguments with different types.

-- 
Ignacio Vazquez-Abrams  <ignacio@openservices.net>





^ permalink raw reply	[flat|nested] 158+ messages in thread
[parent not found: <200108281746.f7SHk1O27199@lists.us.dell.com>]
[parent not found: <20010825024248.J8296@router.ranmachan.dyndns.org>]
[parent not found: <20010825021651.I8296@router.ranmachan.dyndns.org>]
* [IDEA+RFC] Possible solution for min()/max() war
@ 2001-08-24 22:42 Brad Chapman
  2001-08-24 23:21 ` Ben LaHaise
  0 siblings, 1 reply; 158+ messages in thread
From: Brad Chapman @ 2001-08-24 22:42 UTC (permalink / raw)
  To: linux-kernel

Everyone,

	At the risk of igniting another long-drawn-out flamewar over the
min()/max() macros, I have an idea.

	There is a section in the config dialogs labeled "Kernel hacking."
Under it there is the SysRQ option. Why don't we put an entry under that
dialog and label it "Use new min()/max() macros" and make it a y/n field.
Then we can add dozens of warnings to the help dialog about it, and allow
the user/hacker to select the macro they want.

	In any code which uses the macros, you can simply do this:

#include <linux/config.h>
....
#ifdef CONFIG_USE_NEW_MINMAX
	minimum = min(int, number[0], number[1]);
#else
	minimum = min(number[0], number[1]);
#endif

	This way, some hackers can use the two-arg min()/max() inside an #ifdef block,
other hackers can use the three-arg min()/max() inside an #ifdef block, 
and people who don't care can select either.

	Comments, flames, suggestions, anyone? If the output is good, I'll
publish a patch which will add the Config.in option and default it to
CONFIG_USE_NEW_MINMAX=y, since that was the decree of the Great Penguin Overlord ;)

Brad

=====
Brad Chapman

Permanent e-mail: kakadu_croc@yahoo.com
Current e-mail: kakadu@adelphia.net
Alternate e-mail: kakadu@netscape.net

__________________________________________________
Do You Yahoo!?
Make international calls for as low as $.04/minute with Yahoo! Messenger
http://phonecard.yahoo.com/

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

end of thread, other threads:[~2001-09-07 18:03 UTC | newest]

Thread overview: 158+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-08-30 20:44 [IDEA+RFC] Possible solution for min()/max() war Herbert Rosmanith
2001-08-30 21:06 ` Peter T. Breuer
2001-08-30 21:14   ` David Woodhouse
2001-08-30 21:32     ` Peter T. Breuer
2001-08-30 21:47       ` David Woodhouse
2001-08-30 21:56         ` Peter T. Breuer
2001-08-30 22:13           ` David Woodhouse
2001-08-30 22:47             ` Peter T. Breuer
2001-08-30 23:02               ` David Woodhouse
2001-08-31  0:08           ` Daniel Phillips
2001-08-30 21:49       ` Mark Zealey
2001-08-30 22:06         ` Peter T. Breuer
2001-08-30 22:14           ` Mark Zealey
2001-08-31  7:04   ` Herbert Rosmanith
2001-08-30 21:17 ` Richard B. Johnson
2001-08-30 21:45   ` Thomas Dodd
2001-08-30 21:46   ` Peter T. Breuer
2001-08-30 23:16   ` David Woodhouse
2001-08-30 23:33   ` David Wagner
2001-08-31 11:18   ` Bernd Schmidt
     [not found] <m2bskndlkt.fsf@sympatico.ca>
2001-09-07 17:39 ` Peter T. Breuer
  -- strict thread matches above, loose matches on Subject: below --
2001-09-06  1:51 Rick Hohensee
2001-09-06 10:12 ` VDA
2001-09-04 13:17 Petr Vandrovec
2001-09-04  9:09 VDA
2001-09-03 23:16 David desJardins
2001-09-03 20:35 David desJardins
2001-09-04  8:08 ` VDA
     [not found] <fa.eeq0k8v.1v28iaa@ifi.uio.no>
2001-08-31 18:40 ` Ted Unangst
2001-08-31 18:29 Andy Chou
2001-08-31 18:52 ` Roman Zippel
2001-08-31 18:24 Herbert Rosmanith
2001-08-31 18:13 Herbert Rosmanith
2001-08-31 17:41 Herbert Rosmanith
2001-08-31 17:57 ` Rik van Riel
     [not found] <fa.ehba65v.10i6abc@ifi.uio.no>
     [not found] ` <fa.odqvefv.g4k4j6@ifi.uio.no>
2001-08-31 15:45   ` ctm
2001-08-31 16:57     ` Roman Zippel
2001-08-31 14:28 Herbert Rosmanith
2001-08-31 14:37 ` Herbert Rosmanith
2001-08-31 14:28 Martin Knoblauch
2001-08-31  2:48 Rick Hohensee
2001-08-31  2:34 Andy Chou
     [not found] <20010830174227.A10673@furble>
2001-08-31  1:19 ` Peter T. Breuer
2001-08-31  2:10   ` Peter T. Breuer
2001-08-31  7:43   ` Jonathan Lundell
2001-08-31  8:27     ` Alex Bligh - linux-kernel
     [not found] <791753058.999219857@[169.254.198.40]>
2001-08-31  0:57 ` Peter T. Breuer
2001-08-30 20:35 Herbert Rosmanith
2001-08-30 17:32 mike_phillips
2001-08-30 17:45 ` Ion Badulescu
2001-08-30  9:56 Herbert Rosmanith
2001-08-30 13:09 ` Helge Hafting
     [not found] <200108291905.f7TJ59T11456@wildsau.idv-edu.uni-linz.ac.at>
2001-08-29 19:11 ` Herbert Rosmanith
2001-08-29  1:33 Ignacio Vazquez-Abrams
     [not found] <200108281746.f7SHk1O27199@lists.us.dell.com>
2001-08-28 19:33 ` Brad Chapman
2001-08-28 19:02   ` David Lang
2001-08-28 20:38     ` Brad Chapman
2001-08-28 19:25       ` David Lang
2001-08-28 20:34   ` Andreas Schwab
2001-08-28 20:42     ` Brad Chapman
2001-08-28 21:04       ` Christopher Friesen
2001-08-29  9:03       ` Helge Hafting
     [not found] <20010825024248.J8296@router.ranmachan.dyndns.org>
2001-08-25  0:54 ` Brad Chapman
     [not found] <20010825021651.I8296@router.ranmachan.dyndns.org>
2001-08-25  0:21 ` Brad Chapman
2001-08-24 22:42 Brad Chapman
2001-08-24 23:21 ` Ben LaHaise
2001-08-24 23:58   ` Brad Chapman
2001-08-25  0:13     ` Alexander Viro
2001-08-25  0:25       ` Brad Chapman
2001-08-25  0:34         ` Alexander Viro
2001-08-25  0:53           ` Brad Chapman
2001-08-25  1:15             ` Alexander Viro
2001-08-25 11:21               ` Brad Chapman
2001-08-27  0:02               ` Rusty Russell
2001-08-28  4:59                 ` Linus Torvalds
2001-08-28  5:20                   ` Alexander Viro
2001-08-28  5:51                     ` Linus Torvalds
2001-08-28 11:10                       ` Alan Cox
2001-08-28 14:15                         ` Linus Torvalds
2001-08-28 20:06                         ` John Alvord
2001-08-28 12:42                   ` Roman Zippel
2001-08-28 13:27                     ` Linus Torvalds
2001-08-28 14:19                       ` Roman Zippel
2001-08-28 15:14                         ` Linus Torvalds
2001-08-28 15:44                           ` Henning P. Schmiedehausen
2001-08-28 15:55                             ` Russell King
2001-08-28 16:05                             ` Alan Cox
2001-08-28 16:53                               ` Roman Zippel
2001-08-28 16:39                           ` Roman Zippel
2001-08-28 21:51                             ` Mike Castle
2001-08-29  0:33                           ` Daniel Phillips
2001-08-29  1:13                             ` Linus Torvalds
2001-08-29 15:42                               ` Daniel Phillips
2001-08-29 16:02                                 ` David Lang
2001-08-29 23:49                                   ` Daniel Phillips
2001-08-30  2:05                                     ` Bill Rugolsky Jr.
2001-08-30  3:28                                     ` Linus Torvalds
2001-08-30 13:10                                       ` Ion Badulescu
2001-08-30 13:17                                         ` David Woodhouse
2001-08-30 13:26                                           ` Ion Badulescu
2001-08-30 16:09                                         ` Linus Torvalds
2001-08-30 16:28                                           ` Ion Badulescu
2001-08-31 12:50                                             ` Jamie Lokier
2001-08-31 13:45                                               ` Roman Zippel
2001-08-31 16:27                                                 ` Jamie Lokier
2001-08-30 16:31                                           ` Ben LaHaise
2001-08-30 16:38                                           ` Peter T. Breuer
2001-08-30 19:51                                             ` David Weinehall
2001-08-30 20:16                                               ` Peter T. Breuer
2001-08-30 20:31                                               ` Daniel Phillips
     [not found]                                             ` <mit.lcs.mail.linux-kernel/200108301638.SAA04923@nbd.it.uc3m.es>
2001-08-30 22:42                                               ` Patrick J. LoPresti
2001-08-30 23:27                                                 ` Peter T. Breuer
2001-08-31  0:55                                                   ` Linus Torvalds
2001-08-31  1:28                                                     ` Peter T. Breuer
2001-08-31 13:22                                                     ` Peter T. Breuer
2001-08-31 14:02                                                       ` Linus Torvalds
2001-08-31 15:34                                                         ` Peter T. Breuer
2001-08-31 12:01                                                   ` Roman Zippel
2001-08-31 12:13                                                     ` Peter T. Breuer
2001-08-31 12:58                                                       ` Roman Zippel
2001-08-31 13:29                                                         ` Peter T. Breuer
2001-08-31 14:12                                                           ` Roman Zippel
2001-08-31 14:28                                                             ` Peter T. Breuer
2001-08-31 16:30                                                               ` Roman Zippel
2001-09-07  0:52                                                   ` Bill Pringlemeir
2001-09-07  7:26                                                     ` Peter T. Breuer
2001-09-07 12:28                                                       ` Horst von Brand
2001-09-07 18:03                                                         ` Mark H. Wood
2001-09-07 10:58                                                     ` Peter T. Breuer
2001-09-07 14:39                                                       ` Bill Pringlemeir
2001-09-07 15:17                                                         ` Peter T. Breuer
2001-08-30 13:49                                       ` Roman Zippel
2001-08-30 16:21                                         ` Linus Torvalds
2001-08-30 16:41                                           ` Christopher Friesen
2001-08-30 16:50                                             ` Linus Torvalds
2001-08-30 17:13                                           ` Roman Zippel
2001-08-31  1:28                                           ` Ion Badulescu
2001-08-31  5:08                                             ` Linus Torvalds
2001-08-31 12:37                                               ` Jamie Lokier
2001-08-31 13:54                                                 ` Linus Torvalds
2001-08-30 17:01                                       ` Daniel Phillips
2001-08-30 17:03                                         ` Peter T. Breuer
2001-08-30 17:26                                           ` Daniel Phillips
2001-08-31  8:04                                           ` Kai Henningsen
2001-08-30 21:16                                         ` Graham Murray
2001-08-30 21:47                                           ` David Weinehall
2001-08-31 10:10                                             ` Helge Hafting
     [not found]                                           ` <mit.lcs.mail.linux-kernel/m266b51c5c.fsf@barnowl.demon.co.uk>
2001-08-30 22:26                                             ` Patrick J. LoPresti
2001-08-28 16:09                         ` Andreas Schwab
2001-08-28 16:47                           ` Roman Zippel
2001-08-28 17:12                             ` Bill Rugolsky Jr.
2001-08-28 17:28                               ` Roman Zippel
2001-08-28 17:29                           ` Richard B. Johnson
2001-08-26 17:59             ` Bill Pringlemeir
2001-08-24 23:59   ` Brad Chapman
2001-08-25  0:07   ` David S. Miller
2001-08-25  0:18     ` Brad Chapman
2001-08-25  0:23     ` David S. Miller

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