Skip to contentSkip to conversation

Possible solution for min()/max() war

IDEA+RFC Peter T. Breuer 3 participants 4 messages Aug 31, 2001 1 message not in the archive

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): 20010830174227.A10673@furble

#1 lore raw

"A month of sundays ago Gordon Oliver wrote:" [Charset ISO-8859-1 unsupported, filtering to ASCII...]

Quoted 7 lines · On 2001.08.30 16:27 Peter T. Breuer wrote:
Quoted 1 line

Possibly. I have little clue as to the real extent of the problem.

You've missed the _vast_ majority of the real problems. And there is
no way to fix some of them...
- if the sizeof the arguments is the same, it is a bug to have signed vs. unsigned.

That's caught by the solution proposed.

Quoted 2 lines

- if the sizeof the arguments is different, it is a bug to have the _larger_ argument unsigned.

This can't be caught at compile time.

Quoted 3 lines

- if one of the arguments is a constant, typeof will give you a mostly arbitrary value, making { unsigned int i,j; j = max(i,5);} return a bug.

?? I don't follow this at all. Typeof is deterministic, since the gcc computer program is deterministic. Typeof MUST return the type of the expression to which it applies. All expressions in C have precisely computed types -I guess what you are saying is that that the type of an expression may be context dependent, which I can easily imagine in a random computer language, but seriously doubt for C. C really does type calculations via narrowing :-o! Oh yeah!

Show me an instance of an expression that two differnt types depending on context. I am prepared to be surprised, but dubious.

(umm ... what type is the "5" in "(short)5" ?? Why, signed integer, I believe. It's truncated to short, modulo a language lawyer's second opinion).

Quoted 4 lines

- not forcing the person to actually set the type of the argument will allow things like
{
int user_land_value, buffer_size;

Nice integers.

Quoted 1 line
	user_land_value = magic_from_user_land();

signed integer value.

Quoted 1 line
	buffer_size = min(user_land_value, 10);

well, 10 is a signed integer constant. AFAIK you'd have to write "10u" to get an unsigned integer constant. And yes, the latter would be caught by my solution.

Quoted 4 lines

buffer = memcpy(some_place, some_other_place, buffer_size); /* BOOM
*/
}
to not show a bug at all (10 is signed).

I see no bug.

There would be a bug if 10u were used and user_land_value were negative, since then the result of min would be 10u (and this bug would be flagged by my solution). But as things are, the result is user_land_value.

I just checked.

Quoted 2 lines

Please, can we take this off of lkml... (btw, see the attached file for the bugs).

Are you SURE you can find the bugs! :-)

Peter

#2 lore raw

"Peter T. Breuer wrote:"

Quoted 5 lines

"Gordon Oliver wrote:"

Quoted 2 lines

- if the sizeof the arguments is different, it is a bug to have the _larger_ argument unsigned.

This can't be caught at compile time.

Oops - I misinterpreted what you said. You mean "longer", not "larger". Yes, this can be caught by a variant of the solution I proposed ...

   typeof(x) _x = ~(typeof(x))0;
   typeof(y) _y = ~(typeof(y))0;
   ...
   if (sizeof(_x) > sizeof(_y) && _x > 0)
       BUG();
   if (sizeof(_x) < sizeof(_y) && _y > 0)
       BUG();

Though I'm too sleepy to think about why there's a bug in this case ... Isn't it only a bug if the longer arg is unsigned and the shorter is signed? (I suppose the shorter is promoted with sign and then converted to unsigned but I'm not going to get up and open a book to find out ..).

That would be:

   if (sizeof(_x) > sizeof(_y) && _x > 0 && _y < 0)
       BUG();
   if (sizeof(_x) < sizeof(_y) && _y > 0 && _x < 0)
       BUG();

Moral, always use ints.

Peter

#3 lore raw
In reply to Peter T. Breuer
Quoted 10 lines · Peter T. Breuer

?? I don't follow this at all. Typeof is deterministic, since the gcc computer program is deterministic. Typeof MUST return the type of the expression to which it applies. All expressions in C have precisely computed types -I guess what you are saying is that that the type of an expression may be context dependent, which I can easily imagine in a random computer language, but seriously doubt for C. C really does type calculations via narrowing :-o! Oh yeah!

Show me an instance of an expression that two differnt types depending on context. I am prepared to be surprised, but dubious.

OK.

Quoted 6 lines · Peter T. Breuer

// standard good 'ol faithful version

#define __MIN(x,y) ({\
   typeof(x) _x = x; \
   typeof(y) _y = y; \
   _x < _y ? _x : _y ; \

})

How about typeof(__MIN(u, s)), given unsigned u, int s?

Signature · 1 line
/Jonathan Lundell.
#4 lore raw
Quoted 7 lines
Quoted 5 lines
# define __MIN(x,y) ({\
   typeof(x) _x = x; \
   typeof(y) _y = y; \
   _x < _y ? _x : _y ; \
 })

How about typeof(__MIN(u, s)), given unsigned u, int s?

As this would expand to typeof({typeof(u) _u=u .... ? _u : _s;}) I am willing to bet it wouldn't even compile with either version of min, so it doesn't matter.
--
Alex Bligh