Re: Dustmite always reduced to empty set after two iterations

2017-10-11 Thread Jacob Carlborg via Digitalmars-d-learn

On 2017-10-11 22:36, Nordlöw wrote:

My first idea is to make stderr "core dumped" the invariant. Therefore 
my first try becomes to redirect stderr to stdout (in bash) and grep for 
the pattern 'core dumped' as follows


IIRC, segmentation faults are printed by the shell and not the 
application. There you cannot grep on it because it's not the 
application that prints it. You would need to wrap it in a shell script 
or similar. Although, I'm not sure if that changes when you go through DUB.


--
/Jacob Carlborg


Re: Dustmite always reduced to empty set after two iterations

2017-10-11 Thread Vladimir Panteleev via Digitalmars-d-learn

On Wednesday, 11 October 2017 at 20:36:58 UTC, Nordlöw wrote:

What am I doing wrong?


Invoking dub from dustmite probably isn't going to work well. 
Instead, try using dub's dustmite command:


https://code.dlang.org/docs/commandline#dustmite


Re: Undo?

2017-10-11 Thread Mr. Jonse via Digitalmars-d-learn

A simple(incomplete) undo system.

I'm curious about the overhead. The idea is to wrap any system 
changes using the Add function. This function stores both the 
forward and backward state changes using delegates.


By using forward, we call the action passed to set the data and 
backward will call the action to set the original data.


Delegates are used to avoid having to save the actual data 
manually, but I'm wondering if there is a lot of overhead and how 
the GC will be trashed by this, is there a better way or a better 
mechanism to use?




module undo;
import std.variant;


auto apply(T)(T t, Variant[] values) {
import std.traits : ParameterTypeTuple;
import std.conv : emplace;
alias Types = ParameterTypeTuple!T;
assert(values.length == Types.length);
Types args = void;
foreach(i, ref arg; args) { emplace!(typeof(arg))(&arg, 
values[i].get!typeof(arg))); }


return { t(args); };
}

class Undo
{
UndoNode Root;
UndoNode CurrentNode;


void Add(T, S, A...)(T t, S s, A a)
{
pragma(msg, T, " -- ", S);
pragma(msg, A);


UndoNode n = new UndoNode();
n.Parent = CurrentNode;
if (CurrentNode !is null)
n.ParentBranch = CurrentNode.ParentBranch;
foreach(_; a)
n.Action.Data ~= Variant(_);
if (CurrentNode !is null)
CurrentNode.Children ~= n;
CurrentNode = n;

//t();  
n.Action.cmd = { t(); };
n.Action.inv = apply!S(s, n.Action.Data);

}

void Forward()
{   
CurrentNode.Action.cmd();
}

void Backward()
{   
CurrentNode.Action.inv();
}   

this()
{
CurrentNode = Root;
}
}

struct UndoAction
{
Variant[] Data;
void delegate() cmd;
void delegate() inv;
}


class UndoNode
{
UndoNode Parent;
UndoNode ParentBranch;
UndoNode[] Children;
UndoAction Action;
}




test code


import std.stdio;
import mUndo;


class Data
{
int x = 0;
}






__gshared Undo GlobalUndo = new Undo();

int main(string[] argv)
{

__gshared Data data = new Data();
data.x = -1;
auto globalUndo = GlobalUndo;


globalUndo.Add(
   {
auto oldx = data.x;
data.x = 4;
return oldx;
   },
   (int d){
auto oldx = data.x;
data.x = d;
return oldx;
   }, data.x);

writeln(data.x);
globalUndo.Forward();
writeln(data.x);
globalUndo.Backward();
writeln(data.x);

writeln("--");
getchar();
return 0;
}




Re: Fast removal of character

2017-10-11 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, October 11, 2017 23:06:13 Johan Engelen via Digitalmars-d-
learn wrote:
> I am disappointed to see functions being deprecated, without an
> extensive documentation of how to rewrite them for different
> usage of the deprecated function. It makes me feel that no deep
> thought went into removing them (perhaps there was, I can't tell).
>
> One has to go and browse through the different version _release
> notes_ to find any documentation on how to rewrite them. It would
> have been much better to add it (aswell) to the deprecated
> function documentation.
>
> I have the same problem for std.string.squeeze. The release notes
> only say how to rewrite the `squeeze()` case, but not the
> `squeeze("_")` use case. I guess `uniq!("a=='_' && a == b")` ?
> Great improvement?

Normally, when something is deprecated, replacing it is fairly
straightforward, and documentation usually isn't need at all (simply
pointing someone to the new function generally suffices). Unfortunately,
that isn't really the case here. It was decided years ago that they pattern
functions in std.string should be replaced by regex stuff, but no one ever
did it. It was recently decided to just rip them out anyway, which I have
very mixed feelings about, since I agree that they should go, but how to
replace their functionality in your own code is not necessarily obvious. We
certainly didn't provide functions that did the same thing but took regexes,
which was originally the idea for what would replace them but was never
implemented. IIRC, the only reason that there's _any_ explanation is because
the person who created the PR was pushed to create some examples.

The way this was handled is not very typical of how deprecations are
handled.

- Jonathan M Davis



Re: Fast removal of character

2017-10-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/11/17 7:06 PM, Johan Engelen wrote:

On Wednesday, 11 October 2017 at 22:45:14 UTC, Jonathan M Davis wrote:
On Wednesday, October 11, 2017 22:22:43 Johan Engelen via 
Digitalmars-d- learn wrote:
std.string.removechars is now deprecated. 
https://dlang.org/changelog/2.075.0.html#pattern-deprecate


What is now the most efficient way to remove characters from a 
string, if only one type of character needs to be removed?


```
// old
auto old(string s) {
 return s.removechars(",").to!int;
}

// new?
auto newnew(string s) {
 return s.filter!(a => a != ',').to!int;
}
```


Well, in general, I'd guess that the fastest way to remove all 
instances of a character from a string would be std.array.replace with 
the replacement being the empty string,


Is that optimized for empty replacement?

but if you're feeding it to std.conv.to rather than really using the 
resultant string, then filter probably is faster, because it won't 
allocate. Really though, you'd have to test for your use case and see 
how fast a given solution is.


Performance-wise, I would use neither, as both autodecode (removechars 
by using the opaque/slow foreach decoding) and reencode.


Especially if you are removing a single ascii char.

I am disappointed to see functions being deprecated, without an 
extensive documentation of how to rewrite them for different usage of 
the deprecated function. It makes me feel that no deep thought went into 
removing them (perhaps there was, I can't tell).


One has to go and browse through the different version _release notes_ 
to find any documentation on how to rewrite them. It would have been 
much better to add it (aswell) to the deprecated function documentation.


This should have been done. A deprecation in this manner where there is 
no exact path forward is confusing and unnecessary. If we are 
deprecating a function, the person deprecating the function should have 
had a replacement in mind. The only way the message could be worse is if 
it said "please use other functions in Phobos".


-Steve


Re: Fast removal of character

2017-10-11 Thread Johan Engelen via Digitalmars-d-learn
On Wednesday, 11 October 2017 at 22:45:14 UTC, Jonathan M Davis 
wrote:
On Wednesday, October 11, 2017 22:22:43 Johan Engelen via 
Digitalmars-d- learn wrote:
std.string.removechars is now deprecated. 
https://dlang.org/changelog/2.075.0.html#pattern-deprecate


What is now the most efficient way to remove characters from a 
string, if only one type of character needs to be removed?


```
// old
auto old(string s) {
 return s.removechars(",").to!int;
}

// new?
auto newnew(string s) {
 return s.filter!(a => a != ',').to!int;
}
```


Well, in general, I'd guess that the fastest way to remove all 
instances of a character from a string would be 
std.array.replace with the replacement being the empty string,


Is that optimized for empty replacement?

but if you're feeding it to std.conv.to rather than really 
using the resultant string, then filter probably is faster, 
because it won't allocate. Really though, you'd have to test 
for your use case and see how fast a given solution is.


Yeah :(

I am disappointed to see functions being deprecated, without an 
extensive documentation of how to rewrite them for different 
usage of the deprecated function. It makes me feel that no deep 
thought went into removing them (perhaps there was, I can't tell).


One has to go and browse through the different version _release 
notes_ to find any documentation on how to rewrite them. It would 
have been much better to add it (aswell) to the deprecated 
function documentation.


I have the same problem for std.string.squeeze. The release notes 
only say how to rewrite the `squeeze()` case, but not the 
`squeeze("_")` use case. I guess `uniq!("a=='_' && a == b")` ? 
Great improvement?


- Johan



Re: How to call function with variable arguments at runtime?

2017-10-11 Thread Mr. Jonse via Digitalmars-d-learn

On Tuesday, 10 October 2017 at 08:26:37 UTC, Marc Schütz wrote:

On Tuesday, 10 October 2017 at 02:58:45 UTC, Mr. Jonse wrote:
I need to store a hetrogeneous array of delegates. How can I 
do this but still call the function with the appropriate 
number of parameters at run time?


I have the parameters as Variant[] params and a 
function/delegate pointer(void* for now).


Normally I'd push the parameters on the stack and use a call, 
but I'm sure D has some ability to do this, like apply(foo, 
args) would be the same as foo(args[0], ..., args[1]).


I'm not concerned about type correctness, it should always be 
consistent between what I call and what is stored.


Thanks.


Like so?

import std.variant;

void foo(int a, string b, float c) {
import std.stdio;
writefln("a = %s, b = %s, c = %s", a, b, c);
}

auto apply(alias fn)(Variant[] values) {
import std.traits : ParameterTypeTuple;
import std.conv : emplace;
alias Types = ParameterTypeTuple!fn;
assert(values.length == Types.length);
Types args = void;
foreach(i, ref arg; args) {
// using emplace instead of assignment here to be fully 
correct
emplace!(typeof(arg))(&arg, 
values[i].get!(typeof(arg)));

}
return fn(args);
}

void main() {
Variant[] values = [Variant(1), Variant("Hello world"), 
Variant(3.14159f)];

apply!foo(values);
}



The problem with this is that the function parameters need to be 
known. I do not know them. All I have is a function pointer and 
the arguments in variants.



So, it would work off

void bar(int, string, float) { }


void* foo = &bar;
Variant[] values = [Variant(1), Variant("Hello world"),
Variant(3.14159f)];
apply(foo, values);

So, it has to get the type from the variant at run time and pass 
the value's appropriately.




Re: Fast removal of character

2017-10-11 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, October 11, 2017 22:22:43 Johan Engelen via Digitalmars-d-
learn wrote:
> std.string.removechars is now deprecated.
> https://dlang.org/changelog/2.075.0.html#pattern-deprecate
>
> What is now the most efficient way to remove characters from a
> string, if only one type of character needs to be removed?
>
> ```
> // old
> auto old(string s) {
>  return s.removechars(",").to!int;
> }
>
> // new?
> auto newnew(string s) {
>  return s.filter!(a => a != ',').to!int;
> }
> ```

Well, in general, I'd guess that the fastest way to remove all instances of
a character from a string would be std.array.replace with the replacement
being the empty string, but if you're feeding it to std.conv.to rather than
really using the resultant string, then filter probably is faster, because
it won't allocate. Really though, you'd have to test for your use case and
see how fast a given solution is.

- Jonathan M Davis



Fast removal of character

2017-10-11 Thread Johan Engelen via Digitalmars-d-learn

std.string.removechars is now deprecated.
https://dlang.org/changelog/2.075.0.html#pattern-deprecate

What is now the most efficient way to remove characters from a 
string, if only one type of character needs to be removed?


```
// old
auto old(string s) {
return s.removechars(",").to!int;
}

// new?
auto newnew(string s) {
return s.filter!(a => a != ',').to!int;
}
```

cheers,
   Johan


Dustmite always reduced to empty set after two iterations

2017-10-11 Thread Nordlöw via Digitalmars-d-learn
Once again I need to pick up Dustmite to track down a DMD and LDC 
ICE in release mode for my project. But I can't figure out how 
call Dustmite correctly:


When I build https://github.com/nordlow/phobos-next as

/usr/bin/dub build --compiler=dmd --build=release

it prints

Performing "release" build using dmd for x86_64.
phobos-next 0.2.0+commit.1570.gec0578b0: building 
configuration "library"...


to stdout and

Segmentation fault (core dumped)
dmd failed with exit code 139.

to stderr, along with a (dub) exit status code 2.

My first idea is to make stderr "core dumped" the invariant. 
Therefore my first try becomes to redirect stderr to stdout (in 
bash) and grep for the pattern 'core dumped' as follows


dustmite src "/usr/bin/dub build --root=.. --compiler=dmd 
--build=release 2>&1| grep 'core dumped'"


But this gets reduced to empty set as follows


...
Loading src/zio.d
None => Yes
### ITERATION 0 
= Depth 0 =
[ 0.0%] Remove [] => Yes
Done in 2 tests and 12 secs and 653 ms; reduced to empty set


I've also tried adding the flag

--no-redirect

but then I instead get


...
Loading src/zio.d
None => Segmentation fault (core dumped)
Yes
### ITERATION 0 
= Depth 0 =
[ 0.0%] Remove [] => Segmentation fault (core dumped)
Yes
Done in 2 tests and 11 secs and 122 ms; reduced to empty set


What am I doing wrong?


Re: Assert and undefined behavior

2017-10-11 Thread Eduard Staniloiu via Digitalmars-d-learn

On Wednesday, 11 October 2017 at 09:39:04 UTC, user1234 wrote:
On Wednesday, 11 October 2017 at 09:27:49 UTC, John Burton 
wrote:

[...]
I therefore feel like I ought to not use assert and should 
instead validate my assumptions with an if statement and a 
throw or exit or something.


Yes, that's the way of doing. assert() are just used to test 
the program. the -release option in DMD disable all the 
assert() (excepted assert(0) which is a bit special), so that 
in a release version, only Throwable objects can be used after 
a failure detected.


A small addition to the answers already provided.

As user1234 has already said, asserts are removed in the -release 
build, so, if you have to validate some assumption (ex. the file 
opened) you should use enforce[0].


Cheers,
Eduard

[0] - https://dlang.org/library/std/exception/enforce.html


Re: Assert and undefined behavior

2017-10-11 Thread Ali Çehreli via Digitalmars-d-learn

On 10/11/2017 02:27 AM, John Burton wrote:
> The spec says this :-
>
> "As a contract, an assert represents a guarantee that the code must
> uphold. Any failure of this expression represents a logic error in the
> code that must be fixed in the source code. A program for which the
> assert contract is false is, by definition, invalid, and therefore has
> undefined behaviour."

The important part is that the "program" has undefined behavior 
according to *your* definition because you're the one who asserted that 
something should never have happened:


struct Square {
int side;
int area;

invariant() {
assert(area == side * side); // Could be inside foo()
}

void foo() {
}
}

void main() {
auto s = Square(1, 10);
s.foo();
}

So, you think you wrote your program to never break that assertion. So, 
regardless of the reason for the failure (design error, memory 
corruption, hardware error, etc.), the program is outside of its 
well-defined state (by you).


> I know this might seem like a small or pedantic point

Not only this specific point, but almost everything about assertion 
failures are very important and very interesting. For example, according 
to the text you quoted; the code injected by the compiler, the one that 
dumps a backtrace for an Error, should not be executed either. You have 
no guarantee that that code will really dump a backtrace, whether the 
output will be correct, etc. :/ (There has been many many long 
discussions about these topics on the D newsgroups.)


What gives me comfort is the fact that life is not perfect anyway.[1] 
Things somehow seem to work fine. :)


Ali

[1] Another example is mouse clicks (and screen taps). We have no 
guarantee that we are clicking what we wanted to. Sometimes a new window 
pops up and you click some random button but it works in general.




Re: std.concurrency.setMaxMailboxSize

2017-10-11 Thread RazvanN via Digitalmars-d-learn
On Wednesday, 11 October 2017 at 11:26:11 UTC, rikki cattermole 
wrote:

On 11/10/2017 12:09 PM, RazvanN wrote:

Hi all,

I have seen that the concurrency api has this method specified 
in $title [1] and I was wondering what is the use of it? 
Enabling threads to modify the message box of other threads 
doesn't seem to be a good idea and I can't think of any real 
use case.


Best regards,
RazvanN

[1] 
https://dlang.org/phobos/std_concurrency.html#.setMaxMailboxSize


Main controlling thread setting child threads?

Otherwise I don't remember the last time it was mentioned, so 
I'd say leave it be :)


Shouldn't the thread be in charge of its mailbox size? Otherwise, 
main can pass the max size in the constructor.


std.concurrency.setMaxMailboxSize

2017-10-11 Thread RazvanN via Digitalmars-d-learn

Hi all,

I have seen that the concurrency api has this method specified in 
$title [1] and I was wondering what is the use of it? Enabling 
threads to modify the message box of other threads doesn't seem 
to be a good idea and I can't think of any real use case.


Best regards,
RazvanN

[1] 
https://dlang.org/phobos/std_concurrency.html#.setMaxMailboxSize


Re: struct/class generation

2017-10-11 Thread Daniel Kozak via Digitalmars-d-learn
If you just want to not repeat fields and methods you can use alias this or
mixins:
https://run.dlang.io/is/0UkjTe

On Wed, Oct 11, 2017 at 2:07 PM, drug via Digitalmars-d-learn <
digitalmars-d-learn@puremagic.com> wrote:

> 11.10.2017 14:37, ANtlord пишет:
>
> Hello dear community!
>>
>> I've met a little issue. How can I generate struct or class copying some
>> fields and methods from another struct or class? I've found methods to get
>> fields. They are std.traits.FieldNameTuple and std.traits.FieldTypeTuple
>> but I can't find a method allows getting methods from struct or class.
>>
>> Other words I want to get fields and methods by string values and copy
>> them to my struct. Is it possible? Or do I want something strange?
>>
>> Thanks in advance. Sorry if my English is not clear.
>>
> You need a wrapper, but it would include all fields and methods from base
> struct/class and you just expose only that you need. So it's quite possible
> except I don't known how you can exclude needless fields.
> But FieldNameTuple etc are not enough, your best friend is
> __traits(allMember, ...), iterating over its output and making decision
> what current symbol is and processing it according to its features. It's
> not trivial but not very complex.
>


Two way struct wrapper

2017-10-11 Thread drug via Digitalmars-d-learn
Using `alias this` it's easy to make wrapper for structure that calls 
wrapped structure methods like its own. This is one way - from wrapper 
to wrapped transformation. Is it possible to create the opposite way 
from wrapped to wrapper?


https://run.dlang.io/is/Avyu3I

All calls to Bar is redirected to Foo, but output of Foo is not 
redirected to Bar.


Re: struct/class generation

2017-10-11 Thread drug via Digitalmars-d-learn

11.10.2017 14:37, ANtlord пишет:

Hello dear community!

I've met a little issue. How can I generate struct or class copying some 
fields and methods from another struct or class? I've found methods to 
get fields. They are std.traits.FieldNameTuple and 
std.traits.FieldTypeTuple but I can't find a method allows getting 
methods from struct or class.


Other words I want to get fields and methods by string values and copy 
them to my struct. Is it possible? Or do I want something strange?


Thanks in advance. Sorry if my English is not clear.
You need a wrapper, but it would include all fields and methods from 
base struct/class and you just expose only that you need. So it's quite 
possible except I don't known how you can exclude needless fields.
But FieldNameTuple etc are not enough, your best friend is 
__traits(allMember, ...), iterating over its output and making decision 
what current symbol is and processing it according to its features. It's 
not trivial but not very complex.


Re: std.concurrency.setMaxMailboxSize

2017-10-11 Thread rikki cattermole via Digitalmars-d-learn

On 11/10/2017 12:43 PM, RazvanN wrote:

On Wednesday, 11 October 2017 at 11:26:11 UTC, rikki cattermole wrote:

On 11/10/2017 12:09 PM, RazvanN wrote:

Hi all,

I have seen that the concurrency api has this method specified in 
$title [1] and I was wondering what is the use of it? Enabling 
threads to modify the message box of other threads doesn't seem to be 
a good idea and I can't think of any real use case.


Best regards,
RazvanN

[1] https://dlang.org/phobos/std_concurrency.html#.setMaxMailboxSize


Main controlling thread setting child threads?

Otherwise I don't remember the last time it was mentioned, so I'd say 
leave it be :)


Shouldn't the thread be in charge of its mailbox size? Otherwise, main 
can pass the max size in the constructor.


Callee, versus caller. Just depends how you're thinking of the 
responsibility. You can make arguments either way.


Re: struct/class generation

2017-10-11 Thread rikki cattermole via Digitalmars-d-learn

On 11/10/2017 12:37 PM, ANtlord wrote:

Hello dear community!

I've met a little issue. How can I generate struct or class copying some 
fields and methods from another struct or class? I've found methods to 
get fields. They are std.traits.FieldNameTuple and 
std.traits.FieldTypeTuple but I can't find a method allows getting 
methods from struct or class.


Other words I want to get fields and methods by string values and copy 
them to my struct. Is it possible? Or do I want something strange?


Thanks in advance. Sorry if my English is not clear.


There is no way to get string versions of function bodies.


struct/class generation

2017-10-11 Thread ANtlord via Digitalmars-d-learn

Hello dear community!

I've met a little issue. How can I generate struct or class 
copying some fields and methods from another struct or class? 
I've found methods to get fields. They are 
std.traits.FieldNameTuple and std.traits.FieldTypeTuple but I 
can't find a method allows getting methods from struct or class.


Other words I want to get fields and methods by string values and 
copy them to my struct. Is it possible? Or do I want something 
strange?


Thanks in advance. Sorry if my English is not clear.


Re: std.concurrency.setMaxMailboxSize

2017-10-11 Thread rikki cattermole via Digitalmars-d-learn

On 11/10/2017 12:09 PM, RazvanN wrote:

Hi all,

I have seen that the concurrency api has this method specified in $title 
[1] and I was wondering what is the use of it? Enabling threads to 
modify the message box of other threads doesn't seem to be a good idea 
and I can't think of any real use case.


Best regards,
RazvanN

[1] https://dlang.org/phobos/std_concurrency.html#.setMaxMailboxSize


Main controlling thread setting child threads?

Otherwise I don't remember the last time it was mentioned, so I'd say 
leave it be :)


Re: Assert and undefined behavior

2017-10-11 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, October 11, 2017 09:27:49 John Burton via Digitalmars-d-learn 
wrote:
> The spec says this :-
>
> "As a contract, an assert represents a guarantee that the code
> must uphold. Any failure of this expression represents a logic
> error in the code that must be fixed in the source code. A
> program for which the assert contract is false is, by definition,
> invalid, and therefore has undefined behaviour."
>
> Now I worry about the words "undefined behavior" because in C++
> compiler writers seem to have decided that these words mean that
> it's ok for the compiler to generate code to do whatever it feels
> like even in unconnected code and even before the undefined
> behavior is invoked because some subsequent code has undefined
> behavior.
>
>  From my C++ experience this paragraph tells me that if I use
> "assert" to check my assumptions, and the assertion is false,
> then this could lead to my program failing in unpredictable ways
> unconnected with the actual assertion.
>
> I therefore feel like I ought to not use assert and should
> instead validate my assumptions with an if statement and a throw
> or exit or something.
>
> I feel like a failing assertion should not cause "undefined
> behavior" in the sense it is commonly used in C++ programming
> these days but should have exactly defined behavior that it will
> do nothing if the assert passes and throw the specified exception
> if it fails. Can I safely assume this despite the wording?
>
> I know this might seem like a small or pedantic point, but C++
> compilers can and do use invoking undefined behavior as an excuse
> to do all kinds of unexpected things in generated code these days
> and I want to write safe code :) I feel that if D is specified in
> the same way then assert is not safe for me to use in a real
> program.

If your assertions are failing, you're screwed anyway. If an assertion
fails, then by definition, your program is in an invalid state and who knows
what is going to happen. The whole point of assertions is to catch problems
during development so that you ensure that your code is correct. Not using
them is just making things worse for yourself.

The compiler _may_ use an assertion to inform its code generation by
assuming that the assertion is true (which certainly wouldn't cause you any
problems when not compiling with -release, since a failed assertions would
throw an AssertError and kill your program), and yes, in theory, if you
compile with -release, and an assertion would have failed, and the compiler
did something that assumed that the assertion passed, then maybe things
would be worse, but you're already screwed anyway, because your program is
in an invalid state, because the assertion wasn't true. In reality, I expect
that the compiler does very little at this point to optimize based on
assertions, but any time that it actually does will generally benefit you.

If you're concerned about compiling with -release and having an assertion
that would have failed not result in your program dying like it normally
would, then you can use assert(0), which will be translated to a HLT
instruction with -release. e.g.

if(!cond)
 assert(0);

instead of

assert(cond);

Regardless, you obviously shouldn't be using assertions for anything that
depends on user input. They're for detecting bugs in your program during
development. If you're truly using them for that, then you'll be better off
using them, and not using them is just begging for your program to have more
bugs that you didn't catch.

And the reality of the matter is that if you're looking to avoid undefined
behavior in general, you're screwed. Yes, D is much more likely to define
what should be happening than C/C++ is and thus has less undefined behavior
in general, but not ever allowing for undefined behavior would really harm
performance overall, because it really can help the compiler to optimize
code when it's not forced to do something less efficient just to make it so
that everything is fully defined, and pretty much any language you use is
going to have at least some undefined behavior.

Assertions are a great way to help ensure that you catch bugs in your
program, and if they can help the compiler optimize your code upon occasion,
then all the better (though honestly, I expect that they rarely have any
effect on the optimizer at this point given how little of the work on dmd is
geared towards better optimizing code; some work is done in that area to be
sure, but it's rarely the focus because of how much else needs to be done).

- Jonathan M Davis



Re: Assert and undefined behavior

2017-10-11 Thread user1234 via Digitalmars-d-learn

On Wednesday, 11 October 2017 at 09:27:49 UTC, John Burton wrote:

[...]
I therefore feel like I ought to not use assert and should 
instead validate my assumptions with an if statement and a 
throw or exit or something.


Yes, that's the way of doing. assert() are just used to test the 
program. the -release option in DMD disable all the assert() 
(excepted assert(0) which is a bit special), so that in a release 
version, only Throwable objects can be used after a failure 
detected.




Re: Assert and undefined behavior

2017-10-11 Thread rikki cattermole via Digitalmars-d-learn

On 11/10/2017 10:27 AM, John Burton wrote:

The spec says this :-

"As a contract, an assert represents a guarantee that the code must 
uphold. Any failure of this expression represents a logic error in the 
code that must be fixed in the source code. A program for which the 
assert contract is false is, by definition, invalid, and therefore has 
undefined behaviour."


Now I worry about the words "undefined behavior" because in C++ compiler 
writers seem to have decided that these words mean that it's ok for the 
compiler to generate code to do whatever it feels like even in 
unconnected code and even before the undefined behavior is invoked 
because some subsequent code has undefined behavior.


 From my C++ experience this paragraph tells me that if I use "assert" 
to check my assumptions, and the assertion is false, then this could 
lead to my program failing in unpredictable ways unconnected with the 
actual assertion.


I therefore feel like I ought to not use assert and should instead 
validate my assumptions with an if statement and a throw or exit or 
something.


I feel like a failing assertion should not cause "undefined behavior" in 
the sense it is commonly used in C++ programming these days but should 
have exactly defined behavior that it will do nothing if the assert 
passes and throw the specified exception if it fails. Can I safely 
assume this despite the wording?


I know this might seem like a small or pedantic point, but C++ compilers 
can and do use invoking undefined behavior as an excuse to do all kinds 
of unexpected things in generated code these days and I want to write 
safe code :) I feel that if D is specified in the same way then assert 
is not safe for me to use in a real program.


You misinterpreted it.

The program /could/ be in an invalid state because an internal state 
check (assert) says that it isn't.


What the compiler generates for the assert, depends upon the platform 
and if its building with optimizations. But all of them will end in the 
process crashing unless you go out of your way to handle it.


By default it throws and Error in debug mode, which you shouldn't be 
catching since it is an Error and not an Exception anyway.


Assert and undefined behavior

2017-10-11 Thread John Burton via Digitalmars-d-learn

The spec says this :-

"As a contract, an assert represents a guarantee that the code 
must uphold. Any failure of this expression represents a logic 
error in the code that must be fixed in the source code. A 
program for which the assert contract is false is, by definition, 
invalid, and therefore has undefined behaviour."


Now I worry about the words "undefined behavior" because in C++ 
compiler writers seem to have decided that these words mean that 
it's ok for the compiler to generate code to do whatever it feels 
like even in unconnected code and even before the undefined 
behavior is invoked because some subsequent code has undefined 
behavior.


From my C++ experience this paragraph tells me that if I use 
"assert" to check my assumptions, and the assertion is false, 
then this could lead to my program failing in unpredictable ways 
unconnected with the actual assertion.


I therefore feel like I ought to not use assert and should 
instead validate my assumptions with an if statement and a throw 
or exit or something.


I feel like a failing assertion should not cause "undefined 
behavior" in the sense it is commonly used in C++ programming 
these days but should have exactly defined behavior that it will 
do nothing if the assert passes and throw the specified exception 
if it fails. Can I safely assume this despite the wording?


I know this might seem like a small or pedantic point, but C++ 
compilers can and do use invoking undefined behavior as an excuse 
to do all kinds of unexpected things in generated code these days 
and I want to write safe code :) I feel that if D is specified in 
the same way then assert is not safe for me to use in a real 
program.


Re: Huge increase in UT compile time

2017-10-11 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, October 11, 2017 06:25:19 Dhananjay via Digitalmars-d-learn 
wrote:
> Hello,
>
> I am upgrading to DMD 2.076.1 from DMD 2.069.2 (similar results
> on 2.075.1), and seeing a huge increase in unittest compilation
> time when the -deps parameter is also passed to dmd. This is on
> both OSX and linux. What can be the cause of this?

Well, that's a pretty big version jump. So, a lot could have changed. One
thing that comes to mind would be that imports were overhauled pretty
thoroughly to try and fix various import bugs. This blog article talks about
some of that:

http://www.schveiguy.com/blog/2016/03/import-changes-in-d-2-071/

Or the change could be the result of something else entirely. Figuring it
out would likely require doing a fair bit of debugging to narrow down when
the change happened (and that's assuming that it's caused by a single commit
or small set of commits rather than simply getting worse over time due to a
variety of factors).

- Jonathan M Davis



Re: Why do I have to cast arguments from int to byte?

2017-10-11 Thread Daniel Kozak via Digitalmars-d-learn
You can avoid cast:

void foo(T)(T bar){...}

byte bar = 9;

foo!byte(bar + byte(1));

or

byte bar = 9;
byte num = 1;
foo!byte(bar + num);



On Tue, Oct 10, 2017 at 9:55 PM, Chirs Forest via Digitalmars-d-learn <
digitalmars-d-learn@puremagic.com> wrote:

> I keep having to make casts like the following and it's really rubbing me
> the wrong way:
>
> void foo(T)(T bar){...}
>
> byte bar = 9;
>
> foo!byte(bar + 1); //Error: function foo!byte.foo (byte bar) is not
> callable using argument types (int)
> foo!byte(cast(byte)(bar + 1));
>
> It wouldn't be so bad if I didn't have to use the word cast before each
> cast, bust since I have to specify both the word cast and the cast type and
> then wrap both the cast type and the value in brackets... it just explodes
> my code into multiple lines of unreadable mess.
>
>
> void foo(T)(T bar, T bar2, T bar3){...}
>
> byte foobar = 12;
>
> foo!byte(foobar + 1, foobar + 22, foobar + 333);
> vs.
> foo!byte(cast(byte)(foobar + 1), cast(byte)(foobar + 22),
> cast(byte)(foobar + 333));
>
> Why?
>