Re: Dustmite always reduced to empty set after two iterations
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
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?
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
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
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
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?
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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?
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? >