Re: Confusion over enforce and assert - both are compiled out in release mode

2017-08-27 Thread Moritz Maxeiner via Digitalmars-d-learn

On Sunday, 27 August 2017 at 10:46:53 UTC, Andrew Chapman wrote:

[...]

Oh interesting.  Does DUB support passing through the 
--enable-contracts flag to ldc?  Also, if this is an ldc 
specific thing it's probably not a good idea i'd imagine, since 
in the future one may want to use a GDC, or DMD?


Also, with regards to gdc, its release mode `-frelease` option is 
explicitly specified in the manual as being shorthand for a 
specific set of options:



This is equivalent to compiling with the following options:

gdc -fno-assert -fbounds-check=safe -fno-invariants \
-fno-postconditions -fno-preconditions -fno-switch-errors


As it doesn't seem to turn on/off any other options / 
optimizations, you can use `"dflags-gdc": [...]` to specify your 
own set of "release" options without losing anything.
In particular, I would overwrite dub's default "release" build 
type [1] and add your own per compiler build settings, so dub 
won't pass `-frelease` to gdc when using `dub --build=release`.


[1] https://code.dlang.org/package-format?lang=json#build-types


Confusion over enforce and assert - both are compiled out in release mode

2017-08-27 Thread Andrew Chapman via Digitalmars-d-learn
In the docs regarding contract programming and the use of enforce 
/ assert:

https://dlang.org/library/std/exception/enforce.html

it says:

"enforce is used to throw exceptions and is therefore intended to 
aid in error handling. It is not intended for verifying the logic 
of your program. That is what assert is for. Also, do not use 
enforce inside of contracts (i.e. inside of in and out blocks and 
invariants), because they will be compiled out when compiling 
with -release. Use assert in contracts."


However, I am finding that BOTH enforce and assert are compiled 
out by dmd and ldc in release mode.  Is there a standard way of 
doing what enforce does inside an "in" contract block that will 
work in release mode?


I'm guessing I should write my own function for now.


Re: Confusion over enforce and assert - both are compiled out in release mode

2017-08-27 Thread Moritz Maxeiner via Digitalmars-d-learn

On Sunday, 27 August 2017 at 10:46:53 UTC, Andrew Chapman wrote:
On Sunday, 27 August 2017 at 10:37:50 UTC, Moritz Maxeiner 
wrote:

[...]


Oh interesting.  Does DUB support passing through the 
--enable-contracts flag to ldc?


Sure, using platform specific build settings [1] such as 
`"dflags-ldc": ["--enable-contracts"]`.


Also, if this is an ldc specific thing it's probably not a good 
idea i'd imagine, since in the future one may want to use a 
GDC, or DMD?


If you want to use another compiler that supports it, add the 
appropriate "dflags-COMPILER" setting to your package file.
With regards to dmd: Don't use it for release builds, use gdc or 
ldc (better optimizations).


https://code.dlang.org/package-format?lang=json#build-settings


Re: Building (and including libraries) without dub

2017-08-27 Thread zabruk70 via Digitalmars-d-learn

On Saturday, 26 August 2017 at 09:03:03 UTC, Hasen Judy wrote:
What if I want to include a 3rd party library? Surely before 
dub existed, people were incorporating other libraries in their 
projects.


sometimes pragma("lib", ...) very usefull (if i understand you 
correctly)


https://dlang.org/spec/pragma.html#lib


Re: Confusion over enforce and assert - both are compiled out in release mode

2017-08-27 Thread Andrew Chapman via Digitalmars-d-learn

On Sunday, 27 August 2017 at 10:37:50 UTC, Moritz Maxeiner wrote:

On Sunday, 27 August 2017 at 10:17:47 UTC, Andrew Chapman wrote:

On Sunday, 27 August 2017 at 10:08:15 UTC, ag0aep6g wrote:

[...]


Thanks, that explains it.  I think it's a bit of a shame that 
the "in" blocks can't be used in release mode as the clarity 
they provide for precondition logic is wonderful.


If you need that, you could compile using ldc in release mode 
(which you probably want to do anyway):


--- test.d ---
import std.exception;
import std.stdio;

void foo(int x) in { enforce(x > 0); } body
{

}

void bar(int x) in { assert(x > 0); } body
{

}

void baz(int x) in { if (!(x > 0)) assert(0); } body
{

}

void main()
{
(-1).foo.assertThrown;
(-1).bar;
(-1).baz;
}
--

$ ldc2 test.d
-> failed assert in bar's in contract terminates the program

$ ldc2 -release test.d
-> failed assertThrown in main terminates the program

$ ldc2 -release -enable-contracts test.d
-> failed assert in baz's in contract terminates the program

$ ldc2 -release -enable-contracts -enable-asserts test.d
-> failed assert in bar's in contract terminates the program


Oh interesting.  Does DUB support passing through the 
--enable-contracts flag to ldc?  Also, if this is an ldc specific 
thing it's probably not a good idea i'd imagine, since in the 
future one may want to use a GDC, or DMD?


Re: How to store data when using parallel processing

2017-08-27 Thread Andrew Chapman via Digitalmars-d-learn

On Sunday, 27 August 2017 at 01:58:04 UTC, Jonathan M Davis wrote:

[...]


Thanks Jonathan, that makes sense.  As it turns out, the Mutex 
approach actually makes things slower.  In this case I believe 
trying to use multiple cores isn't worth it.


Cheers.


Re: Confusion over enforce and assert - both are compiled out in release mode

2017-08-27 Thread ag0aep6g via Digitalmars-d-learn

On 08/27/2017 12:02 PM, Andrew Chapman wrote:
However, I am finding that BOTH enforce and assert are compiled out by 
dmd and ldc in release mode.  Is there a standard way of doing what 
enforce does inside an "in" contract block that will work in release mode?


I'm guessing I should write my own function for now.
The whole `in` block is ignored in release mode. Doesn't matter what you 
put in there. Nothing of it will be compiled.


Making a repo of downloaded dub package

2017-08-27 Thread Dukc via Digitalmars-d-learn
More than once I have downloaded a DUB package which almost 
compiles but not quite. The fixes are often so trivial that even 
the user can do them, and the package starts working.


But one may want to create a pull request to fix those issues for 
others too. Is there any way to make the automatically downloaded 
dub package into a git repository which acts as if cloned from 
GitHub before making the changes?


Re: Confusion over enforce and assert - both are compiled out in release mode

2017-08-27 Thread Andrew Chapman via Digitalmars-d-learn

On Sunday, 27 August 2017 at 10:08:15 UTC, ag0aep6g wrote:

On 08/27/2017 12:02 PM, Andrew Chapman wrote:
However, I am finding that BOTH enforce and assert are 
compiled out by dmd and ldc in release mode.  Is there a 
standard way of doing what enforce does inside an "in" 
contract block that will work in release mode?


I'm guessing I should write my own function for now.
The whole `in` block is ignored in release mode. Doesn't matter 
what you put in there. Nothing of it will be compiled.


Thanks, that explains it.  I think it's a bit of a shame that the 
"in" blocks can't be used in release mode as the clarity they 
provide for precondition logic is wonderful.


Re: Confusion over enforce and assert - both are compiled out in release mode

2017-08-27 Thread Moritz Maxeiner via Digitalmars-d-learn

On Sunday, 27 August 2017 at 10:17:47 UTC, Andrew Chapman wrote:

On Sunday, 27 August 2017 at 10:08:15 UTC, ag0aep6g wrote:

On 08/27/2017 12:02 PM, Andrew Chapman wrote:
However, I am finding that BOTH enforce and assert are 
compiled out by dmd and ldc in release mode.  Is there a 
standard way of doing what enforce does inside an "in" 
contract block that will work in release mode?


I'm guessing I should write my own function for now.
The whole `in` block is ignored in release mode. Doesn't 
matter what you put in there. Nothing of it will be compiled.


Thanks, that explains it.  I think it's a bit of a shame that 
the "in" blocks can't be used in release mode as the clarity 
they provide for precondition logic is wonderful.


If you need that, you could compile using ldc in release mode 
(which you probably want to do anyway):


--- test.d ---
import std.exception;
import std.stdio;

void foo(int x) in { enforce(x > 0); } body
{

}

void bar(int x) in { assert(x > 0); } body
{

}

void baz(int x) in { if (!(x > 0)) assert(0); } body
{

}

void main()
{
(-1).foo.assertThrown;
(-1).bar;
(-1).baz;
}
--

$ ldc2 test.d
-> failed assert in bar's in contract terminates the program

$ ldc2 -release test.d
-> failed assertThrown in main terminates the program

$ ldc2 -release -enable-contracts test.d
-> failed assert in baz's in contract terminates the program

$ ldc2 -release -enable-contracts -enable-asserts test.d
-> failed assert in bar's in contract terminates the program


Re: 2 Dimensional Array Sorting

2017-08-27 Thread Vino.B via Digitalmars-d-learn

On Saturday, 26 August 2017 at 10:53:03 UTC, Vino.B wrote:

On Saturday, 26 August 2017 at 10:45:13 UTC, Vino.B wrote:

On Saturday, 26 August 2017 at 10:07:53 UTC, user1234 wrote:

[...]


Hi,

 Now there is no duplicate , but the sequence is still not 
correct


[...]


Hi,

  If I execute the script several time's i still get the 
duplicate entries.


From,
Vino.B


Hi,

  After analyzing a bit further was able to find that the  out 
data before sorting is like below(4 - 2 dimensional array) hence 
the sorting is not working, so may i know how do i make this as a 
single 2 dimensional array like below


Required:
[["C:\\Temp\\TEAM2\\TEAM\\DIR1", "40"], 
["C:\\Temp\\TEAM2\\TEAM\\DIR2", "2228"], 
["C:\\Temp\\TEAM3\\EXPORT\\dir2", "61"], 
["C:\\Temp\\TEAM2\\PROD_TEAM\\dir1", "35772"], 
["C:\\Temp\\TEAM2\\BACKUP\\dir1", "35732"], 
["C:\\Temp\\TEAM3\\BACKUP\\dir1", "71465"], 
["C:\\Temp\\TEAM2\\EXPORT\\dir2", "30"]]


Output:
[["C:\\Temp\\TEAM2\\TEAM\\DIR1", "40"], 
["C:\\Temp\\TEAM2\\TEAM\\DIR2", "2228"], 
["C:\\Temp\\TEAM3\\EXPORT\\dir2", "61"]] - 2darray 1


[["C:\\Temp\\TEAM2\\PROD_TEAM\\dir1", "35772"]] - 2darray 2

[["C:\\Temp\\TEAM2\\BACKUP\\dir1", "35732"], 
["C:\\Temp\\TEAM3\\BACKUP\\dir1", "71465"]]  - 2darray 3


[["C:\\Temp\\TEAM2\\EXPORT\\dir2", "30"]]  - 2darray 4

From,
Vino.B



Re: gcd with doubles

2017-08-27 Thread Moritz Maxeiner via Digitalmars-d-learn

On Sunday, 27 August 2017 at 19:47:59 UTC, Alex wrote:

Hi, all.
Can anybody explain to me why

void main()
{
import std.numeric;
assert(gcd(0.5,32) == 0.5);
assert(gcd(0.2,32) == 0.2);
}

fails on the second assert?

I'm aware, that calculating gcd on doubles is not so obvios, as 
on integers. But if the library accepts doubles, and basically 
the return is correct occasionally, why it is not always the 
case?


If the type isn't a builtin integral and can't be bit shifted, 
the gcd algorithm falls back to using the Euclidean algorithm in 
order to support custom number types, so the above gdc in the 
above reduces to:


---
double gcd(double a, double b)
{
while (b != 0)
{
auto t = b;
b = a % b;
a = t;
}
return a;
}
---

The issue boils down to the fact that `32 % 0.2` yield `0.2` 
instead of `0.0`, so the best answer I can give is "because 
floating points calculations are approximations". I'm actually 
not sure if this is a bug in fmod or expected behaviour, but I'd 
tend to the latter.



Is there a workaround, maybe?


If you know how many digits of precision after the decimal dot 
you can multiply beforehand, gcd in integer realm, and div 
afterwards (be warned, the below is only an example 
implementation for readability, it does not do the required 
overflow checks for the double -> ulong conversion!):


---
import std.traits : isFloatingPoint;
T gcd(ubyte precision, T)(T a, T b) if (isFloatingPoint!T)
{
import std.numeric : _gcd = gcd;
immutable T coeff = 10 * precision;
return (cast(T) _gcd(cast(ulong) (a * coeff),
 cast(ulong) (b * coeff))) / coeff;
}
---


gcd with doubles

2017-08-27 Thread Alex via Digitalmars-d-learn

Hi, all.
Can anybody explain to me why

void main()
{
import std.numeric;
assert(gcd(0.5,32) == 0.5);
assert(gcd(0.2,32) == 0.2);
}

fails on the second assert?

I'm aware, that calculating gcd on doubles is not so obvios, as 
on integers. But if the library accepts doubles, and basically 
the return is correct occasionally, why it is not always the case?

Is there a workaround, maybe?


Re: Unable to set static data member of a class (results in default value 0)

2017-08-27 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 27 August 2017 at 22:21:11 UTC, Enjoys Math wrote:

   static int dataReadDelay;


That's thread-local. Use shared to make it shared across all 
threads, and/or initialize it in the same thread as the use.



See:
https://dlang.org/migrate-to-shared.html
https://tour.dlang.org/tour/en/multithreading/thread-local-storage


Re: Comparison of Enumerations with base type of String?

2017-08-27 Thread Michael Reiland via Digitalmars-d-learn
whoa, you can use a struct as a basetype for an enum?  I'm 
guessing it allows you to associate more information with the 
enum without using lookup tables and the like?  And equality is 
probably just a memberwise comparison of the struct itself?


That seems interesting like an interesting idea, although I'm not 
sure if I'd ever use it.


I'm mostly just trying to get a feel for how things work 
underneath so I have a general understanding of the performance 
implications of things (in a very general sense).


Thanks for the indepth responses, I've learned a few things from 
them.





Re: gcd with doubles

2017-08-27 Thread Moritz Maxeiner via Digitalmars-d-learn

On Sunday, 27 August 2017 at 19:47:59 UTC, Alex wrote:

[..]
Is there a workaround, maybe?


To expand on the earlier workaround: You can also adapt a 
floating point to string algorithm in order to dynamically 
determine an upper bound on the number of after decimal point 
digits required. Below is an untested adaption of the reference C 
implementation of errol0[1] for that purpose (MIT license as that 
is what the original code is under):


---
void main()
{
assert(gcd(0.5, 32) == 0.5);
assert(gcd(0.2, 32) == 0.2);

assert(gcd(1.3e2, 3e-5) == 1e-5);
}

template gcd(T)
{
import std.traits : isFloatingPoint;

T gcd(T a, T b)
{
static if (isFloatingPoint!T)
{
return fgcd(a, b);
}
else
{
import std.numeric : igcd = gcd;
return igcd(a, b);
}
}

static if (isFloatingPoint!T)
{
import std.math : nextUp, nextDown, pow, abs, isFinite;
import std.algorithm : max;

T fgcd(T a, T b)
in
{
assert (a.isFinite);
assert (b.isFinite);
assert (a < ulong.max);
assert (b < ulong.max);
}
body
{
short a_exponent;
int a_digitCount = errol0CountOnly(abs(a), 
a_exponent);


short b_exponent;
int b_digitCount = errol0CountOnly(abs(b), 
b_exponent);


a_digitCount -= a_exponent;
if (a_digitCount < 0)
{
a_digitCount = 0;
}

b_digitCount -= b_exponent;
if (b_digitCount < 0)
{
b_digitCount = 0;
}

auto coeff = pow(10, max(a_digitCount, b_digitCount));
assert (a * coeff < ulong.max);
assert (b * coeff < ulong.max);
return (cast(T) euclid(cast(ulong) (a * coeff),
   cast(ulong) (b * coeff))) / 
coeff;

}

ulong euclid(ulong a, ulong b)
{
while (b != 0)
{
auto t = b;
b = a % b;
a = t;
}
return a;
}

struct HighPrecisionFloatingPoint
{
T base, offset;

void normalize()
{
T base = this.base;

this.base   += this.offset;
this.offset += base - this.base;
}

void mul10()
{
T base = this.base;

this.base   *= T(10);
this.offset *= T(10);

T offset = this.base;
offset -= base * T(8);
offset -= base * T(2);

this.offset -= offset;

normalize();
}

void div10()
{
T base = this.base;

this.base   /= T(10);
this.offset /= T(10);

base -= this.base * T(8);
base -= this.base * T(2);

this.offset += base / T(10);

normalize();
}
}
alias HP = HighPrecisionFloatingPoint;

enum epsilon = T(0.001);
ushort errol0CountOnly(T f, out short exponent)
{
ushort digitCount;

T ten = T(1);
exponent = 1;

auto mid = HP(f, T(0));

while (((mid.base > T(10)) || ((mid.base == T(10)) && 
(mid.offset >= T(0 && (exponent < 308))

{
exponent += 1;
mid.div10();
ten /= T(10);
}

while (((mid.base < T(1)) || ((mid.base == T(1)) && 
(mid.offset < T(0 && (exponent > -307))

{
exponent -= 1;
mid.mul10();
ten *= T(10);
}

auto inhi = HP(mid.base, mid.offset + (nextUp(f) - f) 
* ten / (T(2) + epsilon));
auto inlo = HP(mid.base, mid.offset + (nextDown(f) - 
f) * ten / (T(2) + epsilon));


inhi.normalize();
inlo.normalize();

while (inhi.base > T(10) || (inhi.base == T(10) && 
(inhi.offset >= T(0

{
exponent += 1;
inhi.div10();
inlo.div10();
}

while (inhi.base < T(1) || (inhi.base == T(1) && 
(inhi.offset < T(0

{
exponent -= 1;
inhi.mul10();
inlo.mul10();
}

while (inhi.base != T(0) || inhi.offset != T(0))
{
auto hdig = cast(ubyte) inhi.base;
if ((inhi.base == hdig) && (inhi.offset < T(0)))
{
hdig -= 1;
}

auto ldig = cast(ubyte) inlo.base;
if ((inlo.base == ldig) && (inlo.offset < 0))
{
ldig -= 1;

Re: gcd with doubles

2017-08-27 Thread Alex via Digitalmars-d-learn

ok... googled a little bit.
Seems to be the problem of the kind floating poing <--> decimal...
Will try to get by with some division and lrint logic, as there 
is a lack of definition, how to define a gcd in general case.

For example with 30 and 0.16.
Never mind...


Unable to set static data member of a class (results in default value 0)

2017-08-27 Thread Enjoys Math via Digitalmars-d-learn



I have:

class DataSignal : Thread
{
public:
   static int dataReadDelay;

   void run() {
   while (true) {
   Thread.sleep(dur!"msecs"(dataReadDelay));
   // Read in the new file data
   }
   }
}


in main I have:

DataSignal.dataReadDelay = 8000;

// initialize a bunch of signals


Then when each thread is running they sleep for 0 seconds, and I 
can verify that dataReadDelay is staying at 0.  I have 
initialized it no where else.  This seems like a major bug.


Re: Comparison of Enumerations with base type of String?

2017-08-27 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, August 27, 2017 22:01:52 Michael Reiland via Digitalmars-d-learn 
wrote:
> whoa, you can use a struct as a basetype for an enum?  I'm
> guessing it allows you to associate more information with the
> enum without using lookup tables and the like?  And equality is
> probably just a memberwise comparison of the struct itself?
>
> That seems interesting like an interesting idea, although I'm not
> sure if I'd ever use it.

Yeah, you can use pretty much any type as a base type for an enum - though
once you're dealing with heap-allocated objects, it gets a bit entertaining,
just like it does with enums that are manifest constants. e.g.

enum a = [1, 2, 3];

will allocate that array every time that you use the enum. I don't think
that mutable or const classes will work, but you can also use immutable
classes, which should not result in an allocation every time (since they're
immutable, they can be put in the read-only segment by the compiler like
with string literals), but using structs almost certainly makes more sense
if you really want a user-defined type.

Basically, any time you have a group of constants that you want to treat as
a group of constants, an enum can make sense, even if those constants are
structs. Java implemented enums as classes, so this enables similar
capabilities to what you could do with enums in Java. I can't remember if
I've ever used a enum with a base type of struct though. Usually, I either
need ints or strings. I've definitely used manifest constants that are
structs, but actual enums that are structs are not something that I'v
frequently found useful, much as I'm glad that it's possible.

Ultimately, enums really aren't all that different from anything else with
the same base type except that you can't take their address, they're
basically copy-pasted wherever they're used (though it's the value that's
copy-pasted, not the expression used to create the value - so you wouldn't
end up with something like a struct constructor being called), some
operations aren't legal on them which are legal on the base type (mostly
assignment from non-enums), and anything which explicitly checks that
they're an enum may treat them differently. But overall, you'll mostly get
out of an enum what you'd expect from the base type. The only caveat that I
can think of at the moment with regards to performance is that dynamic
arrays (other than strings) result in an allocation every time they're used,
which can be surprising if you're not aware of it, and that applies to
manifest constants as well as proper enums. Really, manifest constants and
proper enums are pretty much the same thing except that proper enums declare
an actual type with a known set of values, whereas a manifest constant
retains its original type. The performance implications should be the same
though. And the fact that they're so similar is part of why the enum keyword
was reused, even though that annoys some folks, since a manifest constant
isn't really an enum.

- Jonathan M Davis



Re: 2 Dimensional Array Sorting

2017-08-27 Thread Vino.B via Digitalmars-d-learn

On Sunday, 27 August 2017 at 11:53:29 UTC, Vino.B wrote:

On Saturday, 26 August 2017 at 10:53:03 UTC, Vino.B wrote:

[...]


Hi,

  After analyzing a bit further was able to find that the  out 
data before sorting is like below(4 - 2 dimensional array) 
hence the sorting is not working, so may i know how do i make 
this as a single 2 dimensional array like below


[...]


Hi,

  Thank you very much, was able to resolve the issue.

From,
Vino.B


Re: No CTFE of function

2017-08-27 Thread Cecil Ward via Digitalmars-d-learn

On Sunday, 27 August 2017 at 00:20:47 UTC, ag0aep6g wrote:

On 08/27/2017 01:53 AM, Cecil Ward wrote:

On Saturday, 26 August 2017 at 23:49:30 UTC, Cecil Ward wrote:

[...]
I think I understand, but I'm not sure. I should have 
explained properly. I suspect what I should have said was 
that I was expecting an _optimisation_ and I didn't see it. I 
thought that a specific instance of a call to my pure 
function that has all compile-time-known arguments would just 
produce generated code that returned an explicit constant 
that is worked out by CTFE calculation, replacing the actual 
code for the general function entirely. So for example


auto foo() { return bar( 2, 3 ); }

(where bar is strongly pure and completely CTFE-able) should 
have been replaced by generated x64 code looking exactly 
literally like

auto foo() { return 5; }
expect that the returned result would be a fixed-length 
literal array of 32-but numbers in my case (no dynamic arrays 
anywhere, these I believe potentially involve RTL calls and 
the allocator internally).


I was expecting this optimisation to 'return literal constant 
only' because I have seen it before in other cases with GDC. 
Obviously generating a call that involves running the 
algorithm at runtime is a performance disaster when it 
certainly could have all been thrown away in the particular 
case in point and been replaced by a return of a precomputed 
value with zero runtime cost. So this is actually an issue 
with specific compilers, but I was wondering if I have missed 
anything about any D general rules that make CTFE evaluation 
practically impossible?


I don't know what might prevent the optimization.

You can force (actual) CTFE with an enum or static variable.
Then you don't have to rely on the optimizer. And the compiler 
will reject the code if you try something that can't be done at 
compile time.


Example:

auto foo() { enum r = bar(2, 3); return r; }


Please don't use the term "CTFE" for the optimization. The two 
are related, of course. The optimizer may literally evaluate 
functions at compile time. But I think we better reserve the 
acronym "CTFE" for the guaranteed/forced kind of 
precomputation, to avoid confusion.


Static had already been tried. Failed. Thanks to your tip, I 
tried enum next. Failed as well, wouldn't compile with GDC.


I tried LDC, which did the right thing in all cases. Optimised 
correctly in every use case to not compute in the generated code, 
just return the literal compile-time calculated result array by 
writing a load of immediate values straight to the destination. 
Hurrah for LDC.


Then tried DMD via web-based edit/compile feature at dlang.org 
website. Refused to compile in the enum case and actually told me 
why, in a very very cryptic way. I worked out that it has a 
problem internally (this is a now an assignment into an enum, so 
I have permission to use the term CTFE now) in that it refuses to 
do CTFE if any variable is declared using an =void initialiser to 
stop the wasteful huge pre-fill with zeros which could take half 
an hour on a large object with slow memory and for all I know 
play havoc with the cache. So simply deleting the = void fixed 
the problem with DMD.


So that's it. There are unknown random internal factors that 
prevent CTFE or CTFE-type optimisation.


I had wondered if pointers might present a problem. The function 
in question originally was specced something like

pure nothrow @nogc @safe
void pure_compute( result_t * p_result, in input_t x )

and just as a test, I tried changing it to

result_t  pure_compute( in input_t x )

instead. I don't think it makes any difference though. I 
discovered the DMD -void thing at that point so this was not 
checked out properly.


Your enum tip was very helpful.

Ps
GDC errors: Another thing that has wasted a load of time is that 
GDC signals errors on lines where there is a function call that 
is fine, yet the only problem is in the body of the function that 
is _being_ called itself, and fixing the function makes the 
phantom error at the call-site go away. This nasty behaviour has 
you looking for errors at and before the call-site, or thinking 
you have the spec of the call args wrong or incorrect types. 
[Compiler-Explorer problem : I am perhaps blaming GDC unfairly, 
because I have only ever used it through the telescope that is 
d.godbolt.org and I am assuming that reports errors on the 
correct source lines. It doesn't show error message text tho, 
which is a nightmare, but nothing to do with the compiler 
obviously.]





Re: Getting error in dmd testsuite

2017-08-27 Thread Joakim via Digitalmars-d-learn

On Saturday, 26 August 2017 at 21:59:10 UTC, Thomas Mader wrote:

Hello,

I am building ldc on Nix (https://nixos.org/nix/) but keep 
getting an error while running the cppa.d test from the dmd 
testsuite (https://github.com/ldc-developers/dmd-testsuite).


1588:  ... runnable/cppa.d -L-lstdc++ (-g) -O
1588: Test failed.  The logged output:
1588: /tmp/nix-build-ldc-1.3.0.drv-0/build/bin/ldmd2 -conf= 
-m64 -Irunnable  -L-lstdc++  
-od/tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable 
-of/tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable/cppa_0 runnable/cppa.d /tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable/cppb.cpp.o
1588: 
/tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable/cppa_0.o: In function `_Dmain':
1588: runnable/cppa.d:(.text._Dmain[_Dmain]+0x49f): undefined 
reference to `int foo15372(int)'
1588: runnable/cppa.d:(.text._Dmain[_Dmain]+0x4b2): undefined 
reference to `Foo15802::boo(int)'
1588: 
/tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable/cppa_0.o:(.data.rel.ro._D4cppa6C131616__vtblZ[_D4cppa6C131616__vtblZ]+0x0): undefined reference to `C13161::dummyfunc()'
1588: 
/tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable/cppa_0.o:(.data.rel.ro._D4cppa4Test6__vtblZ[_D4cppa4Test6__vtblZ]+0x0): undefined reference to `C13161::dummyfunc()'
1588: 
/tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable/cppa_0.o:(.data.rel.ro._D4cppa7C13161a6__vtblZ[_D4cppa7C13161a6__vtblZ]+0x0): undefined reference to `C13161a::dummyfunc()'
1588: 
/tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable/cppa_0.o:(.data.rel.ro._D4cppa5Testa6__vtblZ[_D4cppa5Testa6__vtblZ]+0x0): undefined reference to `C13161a::dummyfunc()'

1588: collect2: error: ld returned 1 exit status
1588: Error: 
/nix/store/df84hkmhrhx1c2zpvrhmk6aprhlzkasx-gcc-wrapper-6.4.0/bin/gcc failed with status: 1

1588:
1588:
1588: ==
1588: Test failed: expected rc == 0, exited with rc == 1
1588:
1588: make[2]: *** [Makefile:335: 
/tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable/cppa.d.out] Error 1


Apart from that all other tests pass.
Any ideas?

It's running on Linux with gcc 6.4.0.


That module tests linking with C++ files, looks like you have 
some symbols that don't match up.  That's weird, because those 
normally work with gcc.  For each of them, use the readelf 
command from binutils to compare the symbols generated and see 
how they differ.  For example,


readelf -sW 
/tmp/nix-build-ldc-1.3.0.drv-0/build/dmd-testsuite/runnable/cppb.cpp.o |grep foo15372


Then run the same command on the D side, ie for cppa_0.o, and 
compare the symbols.


File a bug on the ldc github if you can't figure it out:

https://github.com/ldc-developers/ldc/issues


Re: How to implement Timeout function

2017-08-27 Thread Jerry via Digitalmars-d-learn

On Sunday, 27 August 2017 at 15:56:14 UTC, Saigon wrote:

Hi,

Can I have Timeout function like this one [1] in Ruby? I want 
to check if a TCP service is running, and the check would 
return error if timeout occurs.


Thanks a lot

[1] https://github.com/ruby/ruby/blob/trunk/lib/timeout.rb


Can it be blocking?



How to implement Timeout function

2017-08-27 Thread Saigon via Digitalmars-d-learn

Hi,

Can I have Timeout function like this one [1] in Ruby? I want to 
check if a TCP service is running, and the check would return 
error if timeout occurs.


Thanks a lot

[1] https://github.com/ruby/ruby/blob/trunk/lib/timeout.rb


Re: No CTFE of function

2017-08-27 Thread Cecil Ward via Digitalmars-d-learn

On Sunday, 27 August 2017 at 17:36:54 UTC, Cecil Ward wrote:

On Sunday, 27 August 2017 at 00:20:47 UTC, ag0aep6g wrote:

[...]


Static had already been tried. Failed. Thanks to your tip, I 
tried enum next. Failed as well, wouldn't compile with GDC.


[...]


I wonder if there is anything written up anywhere about what 
kinds of things are blockers to either CTFE or to successful 
constant-folding optimisation in particular compilers or in 
general?


Would be useful to know what to stay away from if you really need 
to make sure that horrendously slow code does not get run at 
runtime. Sometimes it is possible or even relatively easy to 
reorganise things and do without certain practices in order to 
win such a massive reward.


Re: How to implement Timeout function

2017-08-27 Thread Saigon via Digitalmars-d-learn

On Sunday, 27 August 2017 at 15:56:55 UTC, Jerry wrote:

On Sunday, 27 August 2017 at 15:56:14 UTC, Saigon wrote:

Hi,

Can I have Timeout function like this one [1] in Ruby? I want 
to check if a TCP service is running, and the check would 
return error if timeout occurs.


Thanks a lot

[1] https://github.com/ruby/ruby/blob/trunk/lib/timeout.rb


Can it be blocking?


Yes it can in my case.


C callbacks getting a value of 0! Bug in D?

2017-08-27 Thread Johnson Jones via Digitalmars-d-learn
Trying to set a callback for portaudio and it's seeing zero for 
the value passed.


Pa_OpenStream(, input, output, sampleRate, cast(ulong)0, 
cast(PaStreamFlags)(PaStreamFlags.NoFlag + 
0*PaStreamFlags.PrimeOutputBuffersUsingStreamCallback),

 
cast(PaStreamCallback)(a,b,c,d,e,f){
callbackCalled = true;

 return 0;
 }, 
null);

I am using a debug build of portaudio that prints out all the 
parameters before anything else, so it's not an issue with 
portaudio.


I've tried passing a normal function:

__gshared int sawtooth(const(void)* inputBuffer, void* 
outputBuffer, ulong framesPerBuffer, 
const(PaStreamCallbackTimeInfo)* timeInfo, PaStreamCallbackFlags 
statusFlags, void *userData)

{ return 0; }

and passing it as 

with the same issue.

I've tried changing the calling convention and using __gshared 
but the value is always 0. It seems other values are 0 too and 
can't seem to get any value in to the callback(Even a random one).



The output essentially always looks like this:


Opening Stream!
Pa_OpenStream called:
PaStream** stream: 0x00823EA0
PaStreamParameters *inputParameters: NULL
PaStreamParameters *outputParameters: 0x02C6C1C0
PaDeviceIndex outputParameters->device: 3
int outputParameters->channelCount: 4
PaSampleFormat outputParameters->sampleFormat: 1
PaTime outputParameters->suggestedLatency: 0.135000
void *outputParameters->hostApiSpecificStreamInfo: 
0x

double sampleRate: 44100
unsigned long framesPerBuffer: 256
PaStreamFlags streamFlags: 0x0
PaStreamCallback *streamCallback: 0x
void *userData: 0x
Pa_GetSampleSize called:
PaSampleFormat format: 8
Pa_GetSampleSize returned:
int: 2
Pa_GetSampleSize called:
PaSampleFormat format: 8
Pa_GetSampleSize returned:
int: 2
Pa_GetSampleSize called:
PaSampleFormat format: 1
Pa_GetSampleSize returned:
int: 4
Pa_GetSampleSize called:
PaSampleFormat format: 8
Pa_GetSampleSize returned:
int: 2
Pa_GetSampleSize called:
PaSampleFormat format: 8
Pa_GetSampleSize returned:
int: 2
Pa_OpenStream returned:
*(PaStream** stream): 0x03BEAD50
PaError: 0 ( Success )


everything seems correct except:

PaStreamCallback *streamCallback: 0x
void *userData: 0x

You can find the full code at

https://forum.dlang.org/thread/lkbswgpsgxynhfyzw...@forum.dlang.org 



This is either a bug in D, an issue with calling conventions, or 
how one passes the data.



The original portaudio open stream function, so you can see that 
it simply prints it's arguments:


PaError Pa_OpenStream( PaStream** stream,
   const PaStreamParameters *inputParameters,
   const PaStreamParameters *outputParameters,
   double sampleRate,
   unsigned long framesPerBuffer,
   PaStreamFlags streamFlags,
   PaStreamCallback *streamCallback,
   void *userData )
{
PaError result;
PaUtilHostApiRepresentation *hostApi = 0;
PaDeviceIndex hostApiInputDevice = paNoDevice, 
hostApiOutputDevice = paNoDevice;
PaStreamParameters hostApiInputParameters, 
hostApiOutputParameters;
PaStreamParameters *hostApiInputParametersPtr, 
*hostApiOutputParametersPtr;



#ifdef PA_LOG_API_CALLS
PA_LOGAPI_ENTER_PARAMS( "Pa_OpenStream" );
PA_LOGAPI(("\tPaStream** stream: 0x%p\n", stream ));

if( inputParameters == NULL ){
PA_LOGAPI(("\tPaStreamParameters *inputParameters: 
NULL\n" ));

}else{
PA_LOGAPI(("\tPaStreamParameters *inputParameters: 
0x%p\n", inputParameters ));
PA_LOGAPI(("\tPaDeviceIndex inputParameters->device: 
%d\n", inputParameters->device ));
PA_LOGAPI(("\tint inputParameters->channelCount: %d\n", 
inputParameters->channelCount ));
PA_LOGAPI(("\tPaSampleFormat 
inputParameters->sampleFormat: %d\n", 
inputParameters->sampleFormat ));
PA_LOGAPI(("\tPaTime inputParameters->suggestedLatency: 
%f\n", inputParameters->suggestedLatency ));
PA_LOGAPI(("\tvoid 
*inputParameters->hostApiSpecificStreamInfo: 0x%p\n", 
inputParameters->hostApiSpecificStreamInfo ));

}

if( outputParameters == NULL ){
PA_LOGAPI(("\tPaStreamParameters *outputParameters: 
NULL\n" ));

}else{
PA_LOGAPI(("\tPaStreamParameters *outputParameters: 
0x%p\n", outputParameters ));
PA_LOGAPI(("\tPaDeviceIndex outputParameters->device: 
%d\n", outputParameters->device ));
PA_LOGAPI(("\tint outputParameters->channelCount: %d\n", 
outputParameters->channelCount ));

Re: C callbacks getting a value of 0! Bug in D?

2017-08-27 Thread Johnson Jones via Digitalmars-d-learn

Looking at the assembly shows something like this:

0041ea98  push 0x0
0041ea9a  push 0x0
0041ea9c  push 0x0
0041ea9e  push dword 0x100
0041eaa3  mov ecx, [typeid(PaStreamParameters)+0xe36fc (0x80d4cc)]
0041eaa9  mov eax, [fs:0x2c]
0041eaaf  mov edx, [eax+ecx*4]
0041eab2  push dword [edx+0x1c]
0041eab8  push dword [edx+0x18]
0041eabe  push dword [ebp-0x54]
0041eac1  push dword [ebp-0x5c]
0041eac4  mov ebx, PA.stream (0x823f30)
0041eac9  push ebx
0041eaca  call dword near [Pa_OpenStream (0x823f18)]

I noticed that those 0's were the values being fed in to the 
function.


I remember converting c_ulong's to ulong's and that they were 
probably uint's in D. Converting those fixed the problem and the 
callback is now called! I converted all the ulongs to uint's but 
there were a few longs and I don't know if they are c_longs or 
d_longs...


Anyways, At least I'm on the right track.



Re: No CTFE of function

2017-08-27 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 27 August 2017 at 17:47:54 UTC, Cecil Ward wrote:


I wonder if there is anything written up anywhere about what 
kinds of things are blockers to either CTFE or to successful 
constant-folding optimisation in particular compilers or in 
general?


Would be useful to know what to stay away from if you really 
need to make sure that horrendously slow code does not get run 
at runtime. Sometimes it is possible or even relatively easy to 
reorganise things and do without certain practices in order to 
win such a massive reward.


The rules for CTFE are outlined in the docs [1]. What is 
described there is all there is to it. If those criteria are not 
met, the function cannot be executed at compile time. More 
importantly, as mentioned earlier in the thread, CTFE will only 
occur if a function *must* be executed at compile time, i.e. it 
is in a context where the result of the function is required at 
compile-time. An enum declaration is such a situation, a variable 
initialization is not.


There are also a couple of posts on the D Blog. Stefan has 
written about the new CTFE engine [1] and I posted something 
showing a compile-time sort. These illustrate the points laid out 
in the documentation.


As for compiler optimizations, there are some basic optimizations 
that will be common across all compilers, and you can google for 
compiler optimizations to find such generalities. Many of these 
apply across languages, and those specific to the C-family 
languages will likely be found in D compilers. Beyond that, I'm 
unaware of any documentation that outlines optimizations in D 
compilers.


[1] https://dlang.org/spec/function.html#interpretation
[2] https://dlang.org/blog/2017/04/10/the-new-ctfe-engine/
[3] https://dlang.org/blog/2017/06/05/compile-time-sort-in-d/