Arithmetic conversions and a surprise with 'max'

div0 div0 at users.sourceforge.net
Fri Jun 11 13:15:08 PDT 2010


On 11/06/2010 21:02, div0 wrote:
> On 11/06/2010 20:00, Ali Çehreli wrote:
>> The following program demonstrates a problem that I just hit. It is a
>> known gotcha of arithmetic conversion rules.
>>
>> The program is trying to center some text around an index of a char
>> array. To avoid negative index values, it calls 'max' to limit the
>> starting offset at 0.
>>
>> import std.algorithm;
>>
>> void main()
>> {
>> // An empty line
>> char[10] line = ' ';
>>
>> // We want to center some text around the first quarter mark
>> int center_of_text = line.length / 4;
>> string text = "01234567";
>>
>> // To be safe, we want to limit the starting index at 0.
>> // (No negative index please!)
>> int start = max(0, center_of_text - text.length / 2);
>>
>> assert(start >= 0); // FAILS!
>> }
>>
>> The problem is due to converting the second argument of max to unsigned.
>>
>> Ali
>
> It's not a 'gotcha of arithmetic conversion rules'.

It is an all. (though max is wrong as well)

uint	a;
int	b;
b = a;

Compiles cleanly. I'm going nuts, I thought that had been disallowed.


> Write your own max function:
>
> import std.algorithm;
> import std.stdio;
>
> /*
> T max(T)(T a, T b)
> {
> if(a > b)
> return a;
> return b;
> }*/
>
> void main(){
>
> // An empty line
> char[10] line = ' ';
>
> // We want to center some text around the first quarter mark
> int center_of_text = line.length / 4;
> string text = "01234567";
>
> // To be safe, we want to limit the starting index at 0.
> // (No negative index please!)
> auto v0 = 0;
> auto v1 = center_of_text - text.length / 2;
> int start = max(v0, v1);
>
> writeln(typeid(typeof(v0)).toString);
> writeln(typeid(typeof(v1)).toString);
> writefln("v1: %d", v1);
> writefln("start: %d", start);
> assert(start >= 0); // FAILS!
> }
>
> If you uncomment the local max you get:
>
> test.d(25): Error: template test.max(T) does not match any function
> template declaration
> test.d(25): Error: template test.max(T) cannot deduce template function
> from argument types !()(int,uint)
>
> There is special magic in std.algorithm.max to make it work.
> Arguably the implementation in std.algorithm.max is wrong.
>
> Allowing mixing of unsigned and signed seems like a bad idea to me.
>
-- 
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk


More information about the Digitalmars-d-learn mailing list