why compiler try use my sqrt not std.math?

Simen Kjærås simen.kjaras at gmail.com
Wed May 8 09:16:28 UTC 2019


On Wednesday, 8 May 2019 at 08:16:27 UTC, KnightMare wrote:
> // ============= test5.d ==============
> import std.stdio, std.conv, std.bigint, std.math, std.algorithm;
>
> ulong sqrt( ulong n ) { return cast( ulong )real( n ).sqrt; }
> ulong sqrt1( ulong n ) { return cast( ulong )real( n 
> ).sqrt.ceil; }
>
> void main() { }
> // ============= EOF test5.d ==============
>
> and result is:
> test5.d(5): Error: std.math.ceil called with argument types 
> (ulong) matches both:
> C:\programz\D\ldc2\bin\..\import\std\math.d(4869):     
> std.math.ceil(real x)
> and:
> C:\programz\D\ldc2\bin\..\import\std\math.d(4982):     
> std.math.ceil(float x)
>
> prog compiles ok when I comment my ulong sqrt( ulong )
>
> IMO about sqrt1 (I tried cast(real)n instead real(n) too with 
> same result)
> real(n).sqrt should to use real std.math.sqrt(real) that 
> returns real. so ceil should be used real std.math.ceil(real). 
> and after that only cast to ulong.
>
> what happened here?

When a function overload is looked up, the most local symbol is 
used. In this case, that's your sqrt function.

We can even prove this by testing sqrt:

import std.math;
ulong sqrt( ulong n ) { return cast( ulong )real( n ).sqrt; }

void main() {
     assert(4UL.sqrt == 2);
}

The above program will hang, since sqrt calls itself recursively.

When you comment out sqrt, the imported sqrt will be used instead.

To combine the overload sets, you will need to explicitly mention 
std.math.sqrt somehow, either:

     import std.math : sqrt;

or

     import std.math;
     alias sqrt = std.math.sqrt;

Once that's done, your code will do the Right Thing™.

--
   Simen


More information about the Digitalmars-d mailing list