Re: Show dialog box for uncaught exception (Windows, lld-link)
On Sunday, 5 May 2024 at 18:28:29 UTC, SimonN wrote: My implementation for the message box is now: According to [UTF-8 Everywhere](https://utf8everywhere.org/#windows), I shouldn't use `MessageBoxA` at all. The `A` means ANSI codepages, _not_ UTF-8. My above code _will_ show garbage output when there is some non-ASCII in the exception message. Better: Convert to UTF-16 yourself and call `MessageBoxW`: version (Windows) { import core.sys.windows.windows; import std.conv; const wstring messageBody = wtext(/* ... */, "\0"); MessageBoxW(null, messageBody.ptr, null, MB_ICONERROR); throw /* ... */; } -- Simon
Re: Show dialog box for uncaught exception (Windows, lld-link)
On Sunday, 5 May 2024 at 17:15:10 UTC, Steven Schveighoffer wrote: } catch(Exception e) { visualDisplayOfException(e); throw e; } Thanks! That's practically the same pattern that I already use for logging: Try-catch near the entry point, show the message, re-throw. My implementation for the message box is now: catch (Throwable t) { import core.sys.windows.windows; const string errText = /* ... parse t ... */ MessageBoxA(null, errText.ptr, null, MB_ICONERROR); } That solves my problem. Even though I don't pass my game's window as the parent of the message box (first argument, where I pass `null`), the graphical game halts before exiting, shows the error, and users can screenshot both together. That's good. From your answer, I'll assume: There is no standardized way in the D ecosystem (e.g., by calling a DRuntime function from my usercode) to opt into displaying such a message box for uncaught exceptions. I have to call third-party APIs myself. Or is there something after all? From reading the 2019 thread [Deactivate windows MessageBox dialog on exception](https://forum.dlang.org/post/tlhjypvsaxzymccfc...@forum.dlang.org), it sounds like we should get an error box when we link with `-subsystem:windows`, and no box otherwise. -- Simon
Show dialog box for uncaught exception (Windows, lld-link)
Hi, for Windows, I link my executables with `lld-link`, whether for 32-bit and 64-bit and whether I've built with LDC or DMD. How can I generate a dialog box for uncaught exceptions that fly out of my executable's `main()`? When I linked with Optlink years ago for Windows 32-bit, it generated an error dialog box for an uncaught exception. But with `lld-link`, the exception's message lands only on stderr. I didn't see anything related in `lld-link -help`. Can I configure DRuntime in a special way at runtime? My application is a graphical game. I close stdout and stderr by passing `-subsystem:windows` to `lld-link` to suppress the extra console window. For a few fatal errors (missing required resources, can't open display, ...), I throw exceptions, log them to logfile, then re-throw them to crash. I can tell Windows users to look in the logfile, but it would be more fitting on Windows to show an error dialog box in addition to the logging. -- Simon
Re: Annotating SortedRange.empty const: Best way to auto-deduce annotations?
On Wednesday, 2 September 2020 at 21:40:59 UTC, Steven Schveighoffer wrote: What they can do is template the `this` parameter. Then if the underlying range supports calling that way, it will work, otherwise it won't. using `template this` should be compatible with the existing code I would think. Thanks! I've never looked much into template this -- at first glance, it offers what inout already offers -- but it sounds like the right tool for the job. (inout would straightaway disallow calls to mutable methods.) https://dlang.org/spec/template.html#template_this_parameter I'll experiment with it! -- Simon
Annotating SortedRange.empty const: Best way to auto-deduce annotations?
Hi, About this issue in Phobos: https://issues.dlang.org/show_bug.cgi?id=21216 SortedRange.empty should be const, .front should be inout Just adding const/inout to SortedRange's methods won't be enough; if we add const/inout here, then many other Phobos ranges need to become const/inout-correct to keep the tests passing. Before I dive deeper into annotating their methods, I would like to verify my assumptions on how template function attribute deduction works: 1) I know that templated functions deduce their own attributes on instantiation. But front()/empty() are non-templated methods within the templated struct SortedRange. Will attribute deduction happen here? 2) Is it sensible/possible to force attribute deduction by declaring empty() in SortedRange as a zero-argument template? I.e.: @property bool empty()() { return this._input.empty; } 3) Should I rather annotate the non-templated SortedRange.empty/.front manually? But with what, then? empty() should probably be const, but it's never @nogc if annotated manually, even if the wrapped range offers empty() @nogc. -- Simon
Re: Mergesort not working
On Sunday, 29 December 2019 at 11:02:34 UTC, Adnan wrote: while (arr1_idx < arr1.length && arr2_idx < arr2.length) result ~= arr1[arr1_idx] < arr2[arr2_idx] ? arr1[arr1_idx++] : arr2[arr2_idx++]; Given an array, it just returns a 1 length array. What's causing this? This loop stops as soon as arr1 _or_ arr2 are exhausted. Then, merge() will wrongly discard the remainder of the array that is not yet exhausted. The templating is good! -- Simon
Re: How does Rebindable suppress the compiler's optimizations for immutable?
Thanks for the detailed answers! Yes, I accept that immutable guarantees should be implemented only during @safe that doesn't call into @trusted. On Friday, 15 February 2019 at 18:59:36 UTC, H. S. Teoh wrote: At the very least, such [union] code should be automatically @system. Sensible. Honestly, I'm pretty sure that Rebindable technically violates the type system to do what it does. Hmm, I remember we discussed this, and I feel the same now about Rebindable. Either the spec gets extra rules for @trusted or unions, or Rebindable generates latent bugs. Think of immutable as hint for the programmer, not for the compiler. Right, if the compilers don't use it yet, I'm fine with that interpretation. It's merely strange that we have this very restrictive const/immutable that is advertized to help optimization, but then the compiler won't take advantage. Let's see how this develops in the long term, whether the spec gets clearer on the allowed optimization.
How does Rebindable suppress the compiler's optimizations for immutable?
std.typecons.Rebindable!(immutable A) is implemented as: private union { immutable(A) original; A stripped; } ...@trusted assignment operators... @property inout(immutable(A)) get() @trusted pure nothrow @nogc inout { return original; } alias get this; This conforms with the D safety spec: All access to the unsafe union goes through the @trusted get() and the trusted assignment operators. Rebindable!(immutable A) r = a1; // r.original is a1 r = a2; // r.original is a2 But the compiler may assume that immutable variables -- such as the immutable(A) original -- never change and thus may optimize code. Since immutable(A) original is assignable in the union, such optimization would produce wrong behavior: In the final line, the compiler could think that r.original is a1 without examining r.original. How does Rebindable prevent the compiler from optimizing according to immutable's rules?
Re: Why does nobody seem to think that `null` is a serious problem in D?
On Monday, 19 November 2018 at 21:23:31 UTC, Jordi Gutiérrez Hermoso wrote: When I was first playing with D, I managed to create a segfault What's the reasoning for allowing this? 100 % agree that there should be non-nullable class references, they're my main missing feature in D. Likewise, I'm astonished that only few D users wish for them. I understand that it's very hard to get @safely right, without code-flow analysis that Walter prefers to keep at minimum throughout D. I'm concerned about the clarity of usercode. I would like to ensure in my function signatures that only non-null class references are accepted as input, or that only non-null class references will be returned. All possibilities in current D have drawbacks: a) Add in/out contracts for over 90 % of the class variables? This is nasty boilerplate. b) Check all arguments for null, check all returned values for null? This is against the philosophy that null should be cost-free. Also boilerplate. c) Declare the function as if it accepts null, but segfault on receiving null? This looks like a bug in the program. Even if c) becomes a convention in the codebase, then when the function segfaults in the future, it's not clear to maintainers whether the function or the caller has the bug. I discussed some ideas in 2018-03: https://forum.dlang.org/post/epjwwtstyphqknavy...@forum.dlang.org -- Simon
Re: merkle reverse
On Thursday, 5 April 2018 at 09:49:58 UTC, Seb wrote: Strings are bi-directional ranges, but they aren't random-access nor have a length chunks requires hasSlicing + hasLength: Okay, thanks for the great references. chunks/slide certainly need the length to decide which, and how many, elements to serve in the final chunk. The crucial part is now that an autodecoded string's final element can be determined in O(1) by looking at up to 4 code units from its un-decoded end, whereas its autodecoded length cannot be found in O(1). -- Simon
Re: merkle reverse
On Thursday, 5 April 2018 at 09:07:52 UTC, Seb wrote: FYI: The problem isn't chunks, but that strings aren't bi-directional ranges (hello ugly auto-decoding!). "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b".byCodeUnit Thanks! Very appropriate because it's all hex digits anyway. Instead of std.experimental.all, one can also import std.utf. Initially, I wondered whether autodecoding was the issue here, but I dismissed it because the OP's example calls retro immediately on a string, which is supposedly not autodecodable as bi-directional. But I should examine retro's implementation because I remember several Phobos functions having special cases for strings (which is exactly the issue of auto-decoding). -- Simon
Re: merkle reverse
On Thursday, 5 April 2018 at 08:12:38 UTC, aerto wrote: This is the bitcoin genesis block merkle root 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b how i can get it at this format 3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a ?? i try it using string merkle = "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"; writeln(merkle.retro.text); and it gives me b33adedfa7b7212ba77cc2e37667f816f78cb13c88a81523a3f98baab4e1e5a4 Here's one solution with std.range.chunks. A small downside is that it needs the array allocation in the middle because chunks cannot offer the bi-directional range necessary for retro. import std.range; import std.algorithm; void main() { string merkle = "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"; assert (merkle.retro.equal( "b33adedfa7b7212ba77cc2e37667f816f78cb13c88a81523a3f98baab4e1e5a4")); assert (merkle.chunks(2).array.retro.joiner.equal( "3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a")); } -- Simon
Re: Fixing 18615, how to handle @safe/pure/nothrow test breakage due to object.opEquals?
On Wednesday, 28 March 2018 at 15:04:27 UTC, Kagamin wrote: See line 1957, attributes are not inferred. Wow, that hit my blind spot. :-O Thanks. I've moved the RebindableCommon.opEquals outside of the attributes and all tests pass, as expected. -- Simon
Fixing 18615, how to handle @safe/pure/nothrow test breakage due to object.opEquals?
Hi, I'm trying to fix Bugzilla 18615, Rebindable!A doesn't use class A's opEquals (returns a is b instead) [1]. The fix looks reasonably obvious, my code is at [2]. Most of the added lines is the unittest; the essence of the fix is: struct RebindableCommon(/* ... */) { // ... bool opEquals(ref const(typeof(this)) rhs) const { return this.original == rhs.original; } } But this breaks several existing unittests throughout Phobos because the comparison in object.d lacks @safe, @nogc, nothrow and pure. For example, unittests in systime.d fail: pure function [...]RebindableCommon[...].opEquals cannot call impure function object.opEquals nothrow function [...]RebindableCommon[...].opEquals may throw std/datetime/systime.d(9006): Error: template instance `std.typecons.Rebindable!(immutable(TimeZone))` error instantiating I'd rather not add attributes to the Rebindable.opEquals because this function sits in a templated struct RebindableCommon, where the compiler should deduce attributes automatically. But I don't want to remove correct attributes from unittests in systime.d either. Can I reasonably continue here to fix 18615? -- Simon [1] https://issues.dlang.org/show_bug.cgi?id=18615 [2] https://github.com/SimonN/phobos/commit/5a6fc6fd905b02e5ff93f2aaeaee2487fe8b38d0
Re: Optional type - how to correctly reset a wrapped immutable T
On Tuesday, 27 March 2018 at 15:28:40 UTC, jmh530 wrote: static if (isMutable!T) bag[0] = rhs; else bag = [rhs]; I like this idea. I'd even take it a step futher: When T is a pointer or class reference, then we can put the reference on the stack (instead of into the array) and handle assignments like Rebindable handles assignments -- provided that Rebindable really is 100 % safe to the outside, see my concerns from 2 posts above. In this case (static if), we won't even declare the array T[] bag, and instead implement as T value, bool isPresent. When T is a mutable value type, it goes on the stack, too. Again no array. When T is a const/immutable/inout value type, we declare the array as before and rebind on assignment with bag = [rhs], as you proposed here. -- Simon
Re: Optional type - how to correctly reset a wrapped immutable T
On Monday, 26 March 2018 at 14:17:03 UTC, Jonathan M Davis wrote: Rebindable does is pretty questionable as far as the type system goes, but it does what it does by forcing pointer semantics on a class reference, so the point is arguable. Yeah, I've always assumed that Rebindable cannot be implemented without internally breaking the type system, then exposing a safe interface. But this sparked my interest, I've dug out the Rebindable code: private mixin template RebindableCommon(T, U, alias This) if (is(T == class) || is(T == interface) || isAssociativeArray!T) { private union { T original; // e.g., immutable(A) for classs A U stripped; // the unqualified type, e.g., A } // ... } Does Rebindable-using code, oblivious of the hacks inside Rebindable, remain 100 % safe even with aggressive compiler optimizations? For class A, inside Rebindable!(immutable A), there is a union of (immutable A) and A. I suspect that the D compiler is allowed to treat this reference to (immutable A) as immutable itself. Have there never been bugs here when, later, stripped = another.stripped;? -- Simon
Re: String Type Usage. String vs DString vs WString
On Monday, 15 January 2018 at 14:44:46 UTC, Adam D. Ruppe wrote: On Monday, 15 January 2018 at 06:18:27 UTC, SimonN wrote: D's foreach [...] will autodecode and silently iterate over dchar, not char, even when the input is string That's not true. foreach will only decode on demand: foreach(c; s) { /* c is a char here, it goes over bytes */ } Thanks for the correction! Surprised I got foreach(c, s) wrong, its non-decoding iteration is even the prominent example in TDPL. Even `each`, the template function that implements a foreach, still infers as char: "aä".each!writeln; // prints a plus two broken characters Only `map` When I wrote "D's ranges", I meant Phobos's range-producing templates; a range itself is again encoding-agnostic.
Re: String Type Usage. String vs DString vs WString
On Monday, 15 January 2018 at 02:05:32 UTC, Chris P wrote: Is usage of one type over the others encouraged? I would use string (UTF-8) throughout the program, but there seems to be no style guideline for this. Keep in mind two gotchas: D's foreach and D's ranges will autodecode and silently iterate over dchar, not char, even when the input is string, not dstring. (It's also possible to explicitly decode strings, see std.utf and std.uni.) If you call into the Windows API, some functions require extra care if everything in your program is UTF-8. But I still agree with the approach to keep everything as string in your program, and then wrap the Windows API calls, as the UTF-8 Everywhere manifesto suggests: http://utf8everywhere.org/ -- Simon
Re: Pass D const pointer to opaque C library: Guarantees? Optimization-safe?
On Saturday, 16 December 2017 at 11:19:36 UTC, Mike Parker wrote: that's a binding, not a wrapper. Right! Not sure what you mean by "safe" you only want to prevent changes on the D side and don't care if they happen on the C side, then that's fine. This, yes. I'd like const-annotated D code because of the static checks, without risking bugs from aggressive compiler assumptions. It's fine it the C side mutates privately. I am ready to take responsibility in case I misjudge whether one of the C functions mutates detectable state or not. Question 2. If yes, can the wrapper sanely declare foo(const A*) instead of foo(A*)? if you pass immutable variables to the function -- if the parameter is const even when the function modifies the variable, D will allow immutable to be passed and you're looking at unexpected behavior. This is the heart of the problem, I've overlooked this. None of my A are immutable, but declaring the bindings as foo(const A*) would take immutables. I would expect SiegeLord to reject such a PR. Only add const to parameters in C function declarations if the C API actually declares those parameters as const. That was my hunch, too. I've asked upstream on the Allegro forums. It would be a drastic change, I'd wager there won't be any const in the API anytime soon. But I'll give them the due time to decide. If no const C API, I'd stick to private wrappers around DAllegro5, with a codebase-wide rule to not pass immutable. In principle, I disagree with him how much weight should be assigned to "probably". Hmm, SiegeLord is a core Allegro 5 developer, he could judge overriding the C API's promises. But I share your sentiment that the public C API should have the final word. Many thanks for the high-quality answer! -- Simon
Pass D const pointer to opaque C library: Guarantees? Optimization-safe?
Hi, I'm calling a C library through a D wrapper. The situation is like this: C library has: struct A { ... }; A* create_a() { ... } void foo(A*) { ... } D wrapper declares: extern (C) { struct A {} A* create_a(); void foo(A*); } My D usercode: const A* a = create_a(); foo(cast(A*) a); We know that const is transitive in D and the compiler may optimize around it. If we cast away const, it's our responsibility that, e.g., the optimized caching from const will not cause bugs. The memory of the A is allocated by the C library. All the D code ever sees is a pointer, an opaque handle to the resource. How will the compiler optimizations behave around this: Question 1. Is that cast still safe in usercode if foo(a) changes some internal values in *a that are undetectable through the C API? Question 2. If yes, can the wrapper sanely declare foo(const A*) instead of foo(A*)? My use case: My const-heavy D usercode calls Allegro 5, a C game/multimedia library without any const in its API, through the D bindings DAllegro5. I'm considering to make a PR implementing question 2. Github issue: https://github.com/SiegeLord/DAllegro5/issues/42 -- Simon
Re: Sort in return statement
On Saturday, 9 December 2017 at 03:24:52 UTC, codephantom wrote: On Saturday, 9 December 2017 at 02:45:35 UTC, rjframe wrote: `sort` returns a SortedRange of ushorts, not an array of ushorts. Make it: ``` import std.array : array; return sort(numbers.take(8)).array; ``` --Ryan That's it! Thanks Ryan. Yes, this works, and your algorithm would even accept arbitary random-access ranges, not merely arrays. But since we start explicitly with a ushort[] that this function has allocated just for this algorithm, we could save the extra allocation by the final call to array(). // ushort[] numbers = ... randomShuffle(numbers); import std.algorithm.sorting : sort; numbers = numbers[0 .. 8]; sort(numbers); return numbers; sort(numbers) does two things: (1) affect the underlying data, (2) return an input range with extra information that this returned range is sorted. But in our example, we don't need to allocate a fresh array from (2). We can return the sorted data from (1), this is already in array-form. -- Simon
Re: Always std.utf.validate, or rely on exceptions?
ketmar wrote: i'd say: "ALWAYS validate before ANY further processing". On Thursday, 2 March 2017 at 17:03:01 UTC, Kagamin wrote: If you expect file with malformed utf that can cause you trouble and want to handle it gracefully, pass its content through validator and catch exception from validator. Thanks. Now, I still call std.stdio.byLine or std.stdio.lines on the raw data, this seems robust with random binary blobs. Then, I validate each line before calling anything else. -- Simon
Always std.utf.validate, or rely on exceptions?
Many functions in std.utf throw UTFException when we pass them malformed UTF, and many functions in std.string throw StringException. From this, I developed a habit of reading user files like so, hoping that it traps all malformed UTF: try { // call D standard lib on string from file } catch (Exception e) { // treat file as bogus // log e.msg } But std.string.stripRight!string calls std.utf.codeLength, which doesn't ever throw on malformed UTF, but asserts false on errors: ubyte codeLength(C)(dchar c) @safe pure nothrow @nogc if (isSomeChar!C) { static if (C.sizeof == 1) { if (c <= 0x7F) return 1; if (c <= 0x7FF) return 2; if (c <= 0x) return 3; if (c <= 0x10) return 4; assert(false); } // ... } Apparently, once my code calls stripRight, I should be sure that this string contains only well-formed UTF. Right now, my code doesn't guarantee that. Should I always validate text from files manually with std.utf.validate? Or should I memorize which functions throw, then validate manually whenever I call the non-throwing UTF functions? What is the pattern behind what throws and what asserts false? -- Simon
Re: Bug after update to 2.072?
I'm not sure how to pass arbitrary dustmite arguments through dub to dustmite. `dub dustmite -h' lists arguments. When dustmite reduces your project to the empty project, maybe try this from the dustmite website: "You can also surround code that is not to be removed around the magic words DustMiteNoRemoveStart and DustMiteNoRemoveStop. Note that if you place them in comments, you won't be able to use --strip-comments." On Sunday, 6 November 2016 at 06:28:32 UTC, Alex wrote: object.Exception@DustMite/dustmite.d(270): Initial test fails (try using --no-redirect for details) This means that dustmite doesn't recognize the unreduced source as buggy. As a sanity test, dustmite runs the given test on the unreduced project, and requires this test to succeed. -- Simon
Re: immutable class can't override opEquals, workaround?
On Sunday, 21 February 2016 at 07:58:42 UTC, Jonathan M Davis wrote: opEquals still works with const and immutable if it's legal to use a class as the key in an AA, it's a bug have a working version of the PR hasn't even been looked at yet from what I can tell, and it's the simplest of the bits that need to be done Thanks for the detailed overview. Judging from the source comment at hack-casting const to mutable, naive improvements affect much more code than I have imagined. The problem and possible solutions are on the radar still, that's satisfying. I understand if it takes more time, even if I too deem it important. -- Simon
immutable class can't override opEquals, workaround?
Hi, immutable class A { int i; this(int arg) { i = arg; } override bool opEquals(Object rhsObj) { auto rhs = cast (immutable(A)) rhsObj; return rhs && i == rhs.i; } } Error by dmd 2.070: ./immutclass.d(4): Error: function immutclass.A.opEquals does not override any function, did you mean to override 'object.Object.opEquals'? My understandings: 1. immutable class A means: All methods have immutable tacked on them implicitly. 2. Object.opEquals doesn't have immutable tacked on it. If I want to override Object.opEquals, I should override without 'immutable'. 3. Overriding opEquals and toHash are necessary to make A behave properly as AA key type. This is incompatible with (2) in an immutable class. 4. I found this thread: How to turn an inout(Object) into a string http://forum.dlang.org/thread/dcobmtogyrmnaqnqy...@forum.dlang.org that I interpret as: The need for the currently-impossible override is acknowledged, but the implementation would bring significant changes to the language, therefore the solution is postponed. The above thread was from mid-2015, but I guess it's still relevant. My workaround is: Make class _A private, and declare every method immutable, except for what Object decrees to be mutable/const/... Then make a public alias A = immutable(_A). Is there something better than this? Has there been any new development on Object method removal? Jonathan M Davis has been pushing this hard 2 years ago, I'd love to see the efforts make it into the language. :-) -- Simon
Re: chain(const(array of class)) fails
On Tuesday, 2 February 2016 at 10:58:35 UTC, Marc Schütz wrote: The constraint that fails is the one with `CommonType`: `CommonType` uses the `?:` operator to derive the common type: I filed a bug report: https://issues.dlang.org/show_bug.cgi?id=15638 Interesting reduced case, so it wasn't chain after all. Thanks for filing the issue already; also thanks to Nic for good test cases. I think Adam D. Ruppe wanted to push more informative template errors -- they'd come in handy. :-) -- Simon
Re: chain(const(array of class)) fails
Sorry for late reply -- but I got around to test a couple more cases! On Monday, 1 February 2016 at 00:19:44 UTC, Nicholas Wilson wrote: Unqaul means remove any const or immutable torn the type Okay, that sounds like our 'const' shouldn't matter. 'const' is the outermost qualifier, and stripping that leaves us with B[] and C[], which were chainable earlier. StaticMap is like a compile time map What this error message says is that there is one candidate function that matches what you are attempting to do. and that chain takes a variadic argument and each of those arguments must 1) when unqualified be an input range (Basically you can foreach over it) Yep, const(B[]) and const(C[]) can be foreached. My workaround has been to replace chain() with several foreaches. 2) that the common type of the element type of the unqualified variadic argument types is not void (in this case not arrays of void) Have you tried changing The declaration of a and b to const(A[])? Surprisingly, this compiles and gives the desired output: const(B[]) b = [ new B(), new B() ]; const(A[]) c = [ new C(), new C() ]; // A instead of C chain(b, c).each!(a => a.val.writeln); With two arguments, const(array) has worked iff at least one range is of the base type. Only if none were of the base type, I got the error. Apparently, the template is smart enough to infer the common base type without 'const', but needs to be fed the basetype in case of 'const'. My gut feeling is that I should report this as a bug against phobos... Also have you tried with other reference type (e.g. assoc arrays pointers)? immutable(B[int]) b; immutable(C[int]) c; chain(b.byValue, c.byValue).each!(a => a.val.writeln); Error is the same as for the classes: template std.range.chain cannot deduce function from argument types !()(Result, Result), candidates are: /* snip */ To get this error, again, if at least one range is 'immutable(A[int]).byValue', i.e., using the base class A, the template instantiates with no problems. -- Simon
chain(const(array of class)) fails
Hi, we start with the following code snippet, which works. import std.algorithm; import std.range; import std.stdio; class A { int val; } class B : A { this() { val = 3; } } class C : A { this() { val = 4; } } B[] b = [new B(), new B()]; C[] c = [new C(), new C()]; void main() { chain(b, c).each!(a => a.val.writeln); } The output, as expected, is: 3 3 4 4 Now I change the declarations of B[] b and C[] c to the following, keeping everything else in the code snippet the same: const(B[]) b = [new B(), new B()]; const(C[]) c = [new C(), new C()]; This makes dmd 2.070 choke: ( http://dpaste.dzfl.pl/eee69fd03dd9 ) Error: template std.range.chain cannot deduce function from argument types !()(const(B[]), const(C[])), candidates are: /opt/compilers/dmd2/include/std/range/package.d(804): std.range.chain(Ranges...)(Ranges rs) if (Ranges.length > 0 && allSatisfy!(iseputRange, staticMap!(Unqual, Ranges)) && !is(CommonType!( staticMap!(ElementType, staticMap!(Unqual, Ranges))) == void)) What's stumping me -- constness doesn't make dmd choke on ranges of numbers. If I replace the classes B and C with simple 'int' and 'double', this compiles again: const(int[])b = [1, 2]; const(double[]) c = [3.3, 4.4]; void main() { chain(b, c).each!(a => a.writeln); } Why does it fail for const(array of class)? Is any template magic about Unqual or staticMap relevant here? -- Simon
Re: @property not available for classes?
On Friday, 1 January 2016 at 10:14:58 UTC, Shriramana Sharma wrote: auto p = TimeSpan(1, 2); Error: no property 'opCall' for type '.TimeSpan' The error should be in 'auto p = ...', not in the line using the property. Instantiate with 'new TimeSpan(1, 2)' instead of 'TimeSpan(1, 2)'. The latter would be the constructor call for a struct. Classes go on the GC'ed heap by default. The property syntax should work. :-) -- Simon
Re: Variable below zero but if statement doesn't grab?
On Sunday, 27 December 2015 at 16:41:10 UTC, TheDGuy wrote: It looks like the debugger is not working correctly because i changed the code to this: [...] and the same problem appears. I can't watch youtube here. What numbers does your input generate? Which 'if' doesn't fire? What results would you like instead? -- Simon
Re: Variable below zero but if statement doesn't grab?
On Sunday, 27 December 2015 at 16:01:37 UTC, TheDGuy wrote: Sry: if((x1 < 0) & (x2 >= 0)){ This looks like a bug, with & instead of &&. -- Simon
Re: Variable below zero but if statement doesn't grab?
On Sunday, 27 December 2015 at 16:52:39 UTC, TheDGuy wrote: I don't understand why my program goes into the if statement if the debugger shows, that the variable "discriminant" is below zero even though: "if(discriminant > 0)"? I have a hard time believing this. Does the problem persist if you swap out the entire control flow, beginning with that line, with the following? if (discriminant > 0) writeln("bigger than zero"); else writeln("not entering the 'if'");
Re: segfault in invariant { assert(super); }
On Monday, 21 December 2015 at 20:29:14 UTC, Steven Schveighoffer wrote: 1) Is this recursion expected? Yes. assert calls the virtual invariant function, which in the case of super is equivalent to this. So you are essentially calling assert(this). 2) The example is a dustmite'd version of this: It seems like something you shouldn't do. AFAIK, invariant should not call any public functions on your existing class. Thanks for the reply! Yeah, this helps for a clearer picture of what's happening. In particular, even though all invariants of a class hierarchy are tested instead of only the most-subclassed-one, triggering the invariant check remains virtual. I didn't know that. Even if Base.f() is const, it's not allowed inside Derived.invariant(). This is again understandable: By OOP principles, Derived shouldn't impose further restrictions on Base than what Base imposes on itself already. (good idea to file an enhancement report). For that, I was trying earlier today to find the exact instances of when there is a warning, and when there is not. I didn't get warnings to come up consistently. (Even the case I described in question 2 doens't always give a warning.) I'd have to take a look at this some time again. -- Simon
segfault in invariant { assert(super); }
Hi, the following code compiles fine, then segfaults upon running. class Base { this(int) { } } class Derived : Base { this(int a) { super(a); } invariant() { assert (super); } } void main() { new Derived(5); } Tested both with dmd 2.069.2 on Linux 64-bit, and on dpaste's dmd 2.069.1: http://dpaste.dzfl.pl/4b9475c668f1 Backtrace on my home machine: Program received signal SIGSEGV, Segmentation fault. 0x004246a5 in _D9invariant12_d_invariantFC6ObjectZv () (gdb) bt #0 0x004246a5 in _D9invariant12_d_invariantFC6ObjectZv () #1 0x00647bf0 in _D3app7Derived6__initZ () #2 0x7f7ff030 in ?? () #3 0x0042301f in _D3app7Derived12__invariant1MxFZv (this=0x0) at source/app.d:7 Backtrace stopped: previous frame inner to this frame (corrupt stack?) So, looks like endless recursion inside the invairant. Questions: 1) Is this recursion expected? 2) The example is a dustmite'd version of this: I have a public final method Base.f(), and the compiler won't let me call f() in Derived's invariant. This is understandable, because f() is also a public method of Derived. However, I can call super.f() explicitly in Derived's invariant, with no compiler error. Is that expected to work, or should it lead to a similar segfault? (I get the segfault.) -- Simon
alias butAtLeast = max; 5.butAtLeast(6);
DMD v2.069.2-b1 on Linux. import std.algorithm; int a = max(5, 6);// works, a == 6 int b = max!(int, int)(5, 6); // works, manual instantiation int c = 5.max(6); // works, UFCS call I would like to use the last syntax, but with an alias. alias butAtLeast = max; // works int d = butAtLeast(5, 6); // works int e = 5.butAtLeast(6); // error: no property 'butAtLeast' for type 'int' Aliasing the instantiated function 'max!(int, int)' instead of aliasing 'max' doesn't help: The 'int e' line will fail with the exact same error. Can I get the alias to work somehow in an UFCS chain? -- Simon
Re: alias butAtLeast = max; 5.butAtLeast(6);
By putting it in the top level. I believe this is intentional but I don't remember the reasoning. On Saturday, 12 December 2015 at 13:34:09 UTC, ZombineDev wrote: This is due to limitation of function-local aliases. If you put the alias outside it will work: http://dpaste.dzfl.pl/4fb06cbbfad2. Thanks for both of these quick replies -- doing it similar to that example, it works for me too now. Good to know this little workaround. I'd love to see the design reason for the limitation. Right now, the error message (property doesn't exist at all) seems to be misleading. But getting all corner cases right is always tricky. :-) Perhaps a simpler way achieve this is to use renamed imports: The Identity template can also helpful in some situations: Thanks, will read for inspiration! -- Simon
Range violation instead of empty slice on a[3 .. 2]
string a = "hello"; string b = a[3 .. 2]; I expect b to become an empty slice, because 3 is >= 2 already after 0 increments, making the slice length 0. Instead, the code throws a range violation. Expressions of this kind come up, e.g., when taking slices near the end of arrays, like "slice = a[b.length .. $];". To make this robust, I need an extra check for b.length > a.length, returning null in this case, otherwise a[b.length .. $]. What's the design reason to prefer throwing over returning an empty slice? -- Simon
Re: Range violation instead of empty slice on a[3 .. 2]
On Saturday, 21 November 2015 at 18:28:51 UTC, BBaz wrote: this is only an error if bounds checking is not turned on. If you compile your example with DMD option "-boundscheck=off", nothing happens, and the slice will be equal (here) to a[3..$]; Thanks for the hint, I tested this with -boundscheck=off. Then, a[3..2] generates a slice length of (size_t.max), again different from what I might want. If the reason for this behavior (huge slice length instead of null slice) is performance during disabled bounds checking, then I'm fine with having to make the extra check. -- Simon
Re: Range violation instead of empty slice on a[3 .. 2]
On Sunday, 22 November 2015 at 00:24:43 UTC, Jonathan M Davis wrote: this is only an error if bounds checking is not turned on. It's a logic error regardless. you're going to have to create a wrapper. Right, I am using a wrapper, and I'm not relying on any behavior of a[3..2] during -boundscheck=off. How does the runtime know that you're not just providing it garbage values? The runtime flags an empty slice as an error here, seemingly without reason, because the slice can't access any element outside of bounds. However, considering (2U - 3U) > 0, I understand that there is no way to catch this problem without comparing the two bounds. And the comparison is designed to be skippable for speed. Therefore, 3..2 is reasonably flagged as an error. So, thanks for pointing it it out again! -- Simon
Mixin template, "no identifier for declarator"
Hi, I'd like to generate several very similar class methods with a mixin template. The mixin template shall take alias parameters, so that different methods can bind it to different fields. Reduced problem case: class A { int myField; mixin template fieldSetter(alias whatField) { whatField = newVal; } int setMyField(in int newVal) { mixin fieldSetter!myField; } } Compiler error message, DMD64 v2.068.2, line 6 is "whatField = newVal;": (6): Error: no identifier for declarator whatField (6): Error: declaration expected, not '=' I believe I'm following as closely as appropriate what's described at http://dlang.org/template-mixin.html under "Mixins can parameterize symbols using alias parameters". Why does it error out on whatField, apparently deeming it to be a type? Can I get this done with mixin templates? (I'd like to avoid string mixins, the workaround with them got a little ugly.) -- Simon
Re: Mixin template, "no identifier for declarator"
On Tuesday, 27 October 2015 at 08:41:24 UTC, Andrea Fontana wrote: Template mixins can be used only for declaration. Thanks for the quick reply! I didn't know that. Now the error message makes sense. Probably what you need is a (non-template) mixin. Yes, it's gonna be a string mixin, or a private method with lots of ref parameters. -- Simon
Re: Arrays of structs
Hi, On Thursday, 27 August 2015 at 10:05:31 UTC, John Burton wrote: understanding is that structs have deterministic destructors - they are called when the struct goes out of scope Yes, when they are declared right at the scope, and not contained in something that might live past the current scope. However if I add them to a dynamic array... Then the destructor appears to be called at some random time later. So it looks like it's the garbage collection that is doing this. Yeah. That seems to go against the specification of how struct works... I'm not creating the item with new and as far as I can tell the array is storing instances of objects, not pointers to objects? The array is storing the full structs, yes. The array is GC-ably allocated and will therefore not go out of scope at end of scope. Because the array doesn't vanish here, the structs inside will not go out of scope either; they treat the array as their scope. (I'm sure others could explain this more formally.) There is no reference left to the array, so the GC may at a random later time deallocate the array, and thereby call ~this() on each struct. Is my understanding correct? Explicit new is not the only way to put objects on the GC'ed heap. Putting them in a GC-ed array like this is another way. Or having them as a component in a class, then instantiating that class. Is it documented anywhere how memory allocation works for this? I'll leave this for others, too. Is a dynamic array in fact storing an array of GC'd pointers to the structs? No, it's the full struct. -- Simon
Re: Empty struct, any runtime cost?
On Wednesday, 19 August 2015 at 09:54:33 UTC, SimonN wrote: Hi, I've found this thread (Theoretical best practises): http://forum.dlang.org/thread/codmadrwuyqxbklmu...@forum.dlang.org My goal is the same; I'm only more wary of putting debug/version everywhere. If the empty struct isn't optimized away fully, I'd still be up for what's recommended in that thread. -- Simon
Empty struct, any runtime cost?
Hi, in a release-like build, I'm using the tharsis profiler, which is a frame-based profiler. Zone is a RAII struct that measures how long its own lifetime is. with (Zone(my_profiler, zone name to appear in output)) { do_expensive_work(); do_some_more_work(); } // Zone goes out of scope here I would like to use this code without modification in a release build without profiling. I would rather not put version statements everywhere. I have only one version statement in a single file that's included by all files doing profiling: version (release_with_profiling) { public import tharsis.prof; } else { class Profiler { } struct Zone { this(Profiler, string) { } } } Using that, the first code sample compiles in the non-profiling build, where Zone is an empty struct. * Will the empty struct get optimized away completely by the compiler, at least if we pass -O -inline? I'd really like that, I have profiling code in several inner loops. * If not, what other approach could be usable to keep boilerplate in most source files to a minimum? -- Simon
Re: Template mixin can not introduce overloads
On Thursday, 25 June 2015 at 03:49:04 UTC, Tofu Ninja wrote: Is this intended or is it a bug? On Thursday, 25 June 2015 at 03:53:58 UTC, Adam D. Ruppe wrote: Intended, the mixin template works on the basis of names. This The extra step is easy though: alias the name in: I would like to to this with constructors instead of normal methods. I have tried to mix in a constructor as follows: #!/usr/bin/rdmd import std.stdio; mixin template MyConstructor() { this(int x, float y) { writefln(%d, %f, x, y); } } class Base { mixin MyConstructor my_ctor; this(string s) { writefln(s); } alias my_ctor this; } void main() { Base b = new Base(3, 4.5); } $ ./mixinctor.d ./mixinctor.d(17): Error: constructor mixinctor.Base.this (string s) is not callable using argument types (int, double) Failed: [dmd, -v, -o-, ./mixinctor.d, -I.] Doing it with alias this = my_ctor; errors out too, and demands me to use alias my_ctor this; as in the original code. Can I get this to work at all? Or does alias this (for multiple subtyping) fundamentally clash here with alias my_ctor this? -- Simon
Re: How to realize copyable/postblit class
On Saturday, 13 June 2015 at 08:52:59 UTC, John Colvin wrote: perhaps: class A { struct S { // ... } S s; alias s this; this(A rhs) { s = rhs.s; } } I'm using this now, and it doesn't feel like a workaround too much. For something with 5 value fields, it's already shorter than the original solution. Thanks! :-) -- Simon
How to realize copyable/postblit class
Hi, I have a few classes with need for deeper copying. I don't want a bitwise copy necessarily. Ideally, I'd implement this(this). I've thought about changing them to struct. However, the type feels much more like a D class than a D struct. It's often passed by reference, and it's not plain old data. Changing it to struct for the sole benefit of this(this) seems to be a bad tradeoff. (Use case: Backing up game states in a for savestating/networking.) I've resorted to a C++-style copy constructor: this(T rhs) { myvalue = rhs.myvalue; myarray = rhs.myarray.dup; // ... } Downside: Boilerplate, each member appears once in the declarations, a second time in the copy constructor. Alternative approaches seem to implement T T.dup() or T T.clone(). Apparently, one has to pick one of these equally good approaches, and stick with it throughout a codebase. It seems good to implement it only for the classes that need it, to minimize boilerplate. Is that the state of the art? -- Simon