Possible solution for min()/max() war
A message that is not in the archive (sent off-list or not yet received): 20010830174227.A10673@furble
"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
{
intuser_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
"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
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.
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