[Issue 18920] core.internal.hash of array of scalars should be `@safe`
https://issues.dlang.org/show_bug.cgi?id=18920 github-bugzi...@puremagic.com changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --
[Issue 18920] core.internal.hash of array of scalars should be `@safe`
https://issues.dlang.org/show_bug.cgi?id=18920 --- Comment #2 from github-bugzi...@puremagic.com --- Commits pushed to master at https://github.com/dlang/druntime https://github.com/dlang/druntime/commit/cb88e333c6d4989a2284c55f48c79dee74cf2457 Fix Issue 18920 - core.internal.hash of array of scalars should be `@safe` https://github.com/dlang/druntime/commit/335cd2e44c230a170394cbebb5269beba0eb4964 Merge pull request #2197 from n8sh/core-hash-18920 Fix Issue 18920 - core.internal.hash of array of scalars should be `@safe` merged-on-behalf-of: Petar Kirov --
[Issue 18922] New: dmd doesn't do substitutions for C++ namespaces in different module/file
https://issues.dlang.org/show_bug.cgi?id=18922 Issue ID: 18922 Summary: dmd doesn't do substitutions for C++ namespaces in different module/file Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: major Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: pro.mathias.l...@gmail.com The following test case: ``` extern(C++, testns) { struct MyStruct { int i; } void func (MyStruct x) {} } ``` Correctly mangles `func` as `__ZN6testns4funcENS_8MyStructE` However, if `MyStruct` is defined in another module, as the following example shows: ``` // File cpp.d module cpp; import data; extern(C++, testns) { void func (MyStruct x) {} } ``` ``` // File data.d module data; extern(C++, testns): struct MyStruct { int i; } ``` dmd will mangle `func` as `_ZN6testns4funcEN6testns8MyStructE`, not doing the namespace substitution correctly. Tested on Mac OSX & Linux x64 with DMD 2.080. This is a blocker for porting any large C++ code base to D, hence classified as major. --
[Issue 18922] dmd doesn't do substitutions for C++ namespaces in different module/file
https://issues.dlang.org/show_bug.cgi?id=18922 Mathias LANG changed: What|Removed |Added Keywords||C++ --
Re: The problem with D's properties
On Thursday, 31 May 2018 at 01:49:42 UTC, DigitalDesigns wrote: https://dpaste.dzfl.pl/6c6e614b58ac The problem given in the list, is that a ref getter is used when a setter does not exist. Why have a setter then? One problem is that if the setter has different behavior than the getter there will be problems. The other problem is that += modifies the value. normally getters are thought to be immutable in the since that they just return a value. but a += will modify what a points to. Using setters, we might want to trigger an event when the value changes. But since the getter is used and can modify the event won't be triggered. This is a bad design. any modifying operator should call the setter. This is precisely what "set mean". a += b is suppose to be syntactic sugar for a = a + b, yet we get different behavior. In one case only a getter is called and in the second case the getter and then the setter. How D currently handles this is wrong and error prone. Either depreciate the use of op assignments using properties or fix it! lvalues should ALWAYS use the setter, it makes no sense otherwise. In case you're not already aware, there is a DIP in progress to remedy this issue: https://github.com/dlang/DIPs/pull/97. A few bugs have already been filed on this, and the DIP intends to address that. If you have anything to add, please voice your thoughts in the DIP's PR. Mike
Re: The problem with D's properties
On Thursday, 31 May 2018 at 01:49:42 UTC, DigitalDesigns wrote: Using setters, we might want to trigger an event when the value changes. But since the getter is used and can modify the event won't be triggered. This is a bad design. Here's similar bad design: --- class Int { public int value; } class Holder { private Int _prop = new Int(10); public Int prop() { return _prop; } public void prop(Int value) { assert(value.value == 10); _prop = value; } } Holder a = new Holder(); a.prop().value = 9; --- I broke an invariant and there's no warning about it. D's properties are indeed broken! Wait, no, that was Java. I mean, C#. Actually, I messed up some -> vs . and missed a couple pointers and it's C++. No, wait, I think it's Dart. Or maybe a new version of Javascript? I can't keep up with ECMA. The problem is that mutable getters and validating setters don't mix. This is easy enough to fix in your code: change `T getter()` to `const(T) getter()`.
Re: The problem with D's properties
On Thursday, 31 May 2018 at 01:49:42 UTC, DigitalDesigns wrote: https://dpaste.dzfl.pl/6c6e614b58ac The problem given in the list, is that a ref getter is used when a setter does not exist. Why have a setter then? [...] Please report issues at https://issues.dlang.org otherwise it will be lost in forums/emails. Whereas if you have the bugzilla ID, it would be a reference to discuss upon.
Re: question about keeeping reference to toStringz()
On Thursday, 31 May 2018 at 01:12:34 UTC, Dr.No wrote: is foo() is being called from a thread, how I am supposed to keep cstring "alive"? As Jonathan explained, you don't have to worry about it if foo() itself doesn't assign the pointer to anything internally. That will be the case for most C functions. Well-behaved functions that need to keep the string around will copy it. That said, you need to be sure you understand fully what any C function you call is doing with the strings, or pointers to any memory allocated by the GC, that you pass to them. In the rare cases where the C function does keep the pointer and you do need to keep a reference (if you don't have one already), the simplest approach is this one: import core.memory; GC.addRoot(cstring); Then, when you no longer need it: GC.removeRoot(cstring); https://dlang.org/phobos/core_memory.html#.GC.addRoot
The problem with D's properties
https://dpaste.dzfl.pl/6c6e614b58ac The problem given in the list, is that a ref getter is used when a setter does not exist. Why have a setter then? One problem is that if the setter has different behavior than the getter there will be problems. The other problem is that += modifies the value. normally getters are thought to be immutable in the since that they just return a value. but a += will modify what a points to. Using setters, we might want to trigger an event when the value changes. But since the getter is used and can modify the event won't be triggered. This is a bad design. any modifying operator should call the setter. This is precisely what "set mean". a += b is suppose to be syntactic sugar for a = a + b, yet we get different behavior. In one case only a getter is called and in the second case the getter and then the setter. How D currently handles this is wrong and error prone. Either depreciate the use of op assignments using properties or fix it! lvalues should ALWAYS use the setter, it makes no sense otherwise.
Re: question about keeeping reference to toStringz()
On Thursday, May 31, 2018 01:12:34 Dr.No via Digitalmars-d-learn wrote: > On Wednesday, 30 May 2018 at 20:43:48 UTC, Ali Çehreli wrote: > > On 05/30/2018 01:09 PM, Dr.No wrote: > > > consider a C function with this prototype: > > >> void foo(const char *baa); > > > > > > Does it means I should do: > > >> string s = ...; > > >> auto cstring = s.toStringz; > > >> foo(cstring); > > > > > > rather just: > > >> foo(s.toStringz); > > > > > > ? > > > > It depends. cstring method above is not sufficient if cstring's > > life is shorter than the C library's use: > > > > void bar() { > > > > string s = ...; > > auto cstring = s.toStringz; > > foo(cstring); > > > > } // <- cstring is gone > > > > What if the library saved that pointer while performing foo()? > > > > If cstring is in module-scope or in a container (e.g. an array) > > that's in module-scope then it's fine. But then, you would have > > to remove it from that container when the C library does not > > need that pointer anymore. > > > > Ali > > is foo() is being called from a thread, how I am supposed to keep > cstring "alive"? If it's being passed to foo, then it should be on the stack until foo returns, in which case, the GC should see it when it scans. It's when foo could keep a reference to the pointer that you have a problem, since then as soon as foo returns, the pointer you passed to foo won't be on the stack anymore. So, in that case, you'd have to store the pointer somewhere in D code so that the GC will see it when scanning. Or are you concerned about something like spinning up a thread, calling foo, and then exiting the thread while foo stores the pointer somewhere? If that's the case, then you'll need to store the pointer in a shared or __gshared variable in D code so that you can still refer to it after the thread terminates. - Jonathan M Davis
Re: What's the purpose of the 'in' keyword ?
On Wednesday, May 30, 2018 22:16:28 aberba via Digitalmars-d-learn wrote: > On Sunday, 27 May 2018 at 16:00:15 UTC, Jonathan M Davis wrote: > > On Sunday, May 27, 2018 16:28:56 Russel Winder via > > > > Digitalmars-d-learn wrote: > >> On Sun, 2018-05-27 at 13:10 +, Adam D. Ruppe via > >> Digitalmars-d-learn > > > > - Jonathan M Davis > > Jonathan, which font were you using in your DConf powerpoint > presentation for source code? It made the code look really > nice... I'd point you to my reply to Ali, since what he figured out will probably tell you better than I could. > and also you have good naming skills. Thanks. I'm glad that someone thinks so. Naming is pretty much the king of bikeshedding in programming, and I've been in far too many arguments on that topic before. Far too often, it seems like no matter what you name something, someone is going to think that the name is terrible. - Jonathan M Davis
Re: question about keeeping reference to toStringz()
On Wednesday, 30 May 2018 at 20:43:48 UTC, Ali Çehreli wrote: On 05/30/2018 01:09 PM, Dr.No wrote: > consider a C function with this prototype: >> void foo(const char *baa); > > Does it means I should do: > >> string s = ...; >> auto cstring = s.toStringz; >> foo(cstring); > > rather just: > >> foo(s.toStringz); > > ? It depends. cstring method above is not sufficient if cstring's life is shorter than the C library's use: void bar() { string s = ...; auto cstring = s.toStringz; foo(cstring); } // <- cstring is gone What if the library saved that pointer while performing foo()? If cstring is in module-scope or in a container (e.g. an array) that's in module-scope then it's fine. But then, you would have to remove it from that container when the C library does not need that pointer anymore. Ali is foo() is being called from a thread, how I am supposed to keep cstring "alive"?
Re: What's the purpose of the 'in' keyword ?
On Wednesday, May 30, 2018 15:28:53 Ali Çehreli via Digitalmars-d-learn wrote: > On 05/30/2018 03:16 PM, aberba wrote: > > On Sunday, 27 May 2018 at 16:00:15 UTC, Jonathan M Davis wrote: > >> On Sunday, May 27, 2018 16:28:56 Russel Winder via Digitalmars-d-learn > >> > >> wrote: > >>> On Sun, 2018-05-27 at 13:10 +, Adam D. Ruppe via > >>> Digitalmars-d-learn > >> > >> - Jonathan M Davis > > > > Jonathan, which font were you using in your DConf powerpoint > > presentation for source code? It made the code look really nice...and > > also you have good naming skills. > > The pdf file has that information in it: > >http://www.identifont.com/similar?76H Well, that's cool - especially since properly telling someone what the font was is kind of hard anyway, since I used latex to generate the slides, and you don't normally select a font directly with latex (rather, normally, you select a font family). I used the beamer package to generate the slides and the listings package for the code blocks. The code blocks were then configured to use \ttfamily for the font, so it's whatever gets selected for the ttfamily family of fonts. - Jonathan M Davis
Re: D's Destructors are What Scott Meyers Warned Us About
On Monday, 28 May 2018 at 22:53:03 UTC, 12345swordy wrote: Interesting... You don't mind me asking your assistance on writing DIP on this? I have one set up already, and I needed help as 1.) This is my first time writing a DIP 2.) I don't know what main course of action to take regarding this issue. I want to write a draft of a DIP related to attribute inference next chance I get (possibly this weekend). It's related to this, so I'll post the draft here. You're very welcome to comment (or send PRs). BTW, I'll just be following these guidelines and using accepted DIPs as examples: https://github.com/dlang/DIPs/blob/master/GUIDELINES.md https://github.com/dlang/DIPs/tree/master/DIPs/accepted
Re: Constructing text with astericks
On Wednesday, 30 May 2018 at 22:57:06 UTC, aberba wrote: How will you approach this problem in D idiomatically? Well, I never bother with "idiomatically", so I can't speak to that, but a simple solution that would work is to realize that what you're basically asking for here is a bitmap. Each letter in your "font" would be a little bitmap that you copy into a destination buffer - itself a larger bitmap. Then, when it is complete, you can draw the destination buffer line by line to the screen. The data for your font may just be a bunch of string arrays in source, or an actual bitmap file you create outside the program and load at runtime or something like that. Just remember that you can't just `buffer ~= letter` - you need to do line by line since the two bitmaps will have different sizes.
Re: Constructing text with astericks
On Wednesday, 30 May 2018 at 22:57:06 UTC, aberba wrote: I've been given a challenge to write texts using asterisks to form the letters. D happen to have an unlimited amount of idioms yet i'm out out ideas as to the simplest approach. Task is to basically take a piece of text and write them as asterisks to the console. * * * * * * * * * * First solution I found was to create a class for each letter...like new A(), new B() and implement the logic withing each class. This doesn't scale and i'll have to write about 24 or more classes. Another complex but "makes sense" solution will be to use a GRID system like old digital watches but i'll need a more complex grid to draw complex letters using a dictionary of REPOPULATED indexes of asterisk for each word. First use the length of the string to compute the grid size and iterate over each character to indentify the dictionary of a letter's indexes to use: * *** ** ** *** ** *** ** *** (an R using a more complex Grid) How will you approach this problem in D idiomatically? I'd use an ascii art approach: - Programatically make bitmaps with each letter rendered using a monospaced font. - use higher order functions to make 2d arrays of ' ' and '*'
Re: Move and CTFE
On Wednesday, May 30, 2018 22:42:13 Q. Schroll via Digitalmars-d-learn wrote: > On Wednesday, 30 May 2018 at 21:02:07 UTC, Jonathan M Davis wrote: > > On Wednesday, May 30, 2018 20:42:38 Q. Schroll via > > > > Digitalmars-d-learn wrote: > >> It seems one cannot std.algorithm.mutation.move objects > >> explicitly. Say I have a non-copyable type > >> [...] > >> It fails because move() cannot be executed at compile time. The > >> reason > >> > >> "memcpy cannot be interpreted at compile time, because it > >> > >> has > >> no available source code" > >> sounds very suspicious. > > > > Why is it suspicious? memcpy is a C function, and you can't > > call C functions during CTFE precisely because the compiler > > doesn't have their source code. You can't call D functions > > either if the compiler doesn't have their source (e.g. if > > you're using a .di file to hide the implementation). > > I definitely do understand the error message and it makes sense > that it fails the way it's implemented. However, it makes no > sense that moving as a concept can fail at CTFE. That's what I > find suspicious. [Maybe 'suspicious' isn't the right term; I > couldn't express it better.] You can move rvalues at CTFE which > proves that the compiler can do it. > > >> Shouldn't it be possible to move at CTFE, > >> too, or does it mean, non-copyable types are practically > >> unusable > >> for CTFE? > > > > You can't do much in the way of pointer or memory manipulation > > during CTFE (e.g. no pointer arithmetic or reinterpret casts). > > So, I don't see how a move could be done during CTFE. Even if > > the source for memcpy were available during CTFE, I suspect > > that it wouldn't be allowed due to the lower level stuff that > > it does. > > That's the explanation why probably all currently possible > library alternatives to memcpy would fail. I suspected that when > encountering the error, but still wonder why memcpy or other > low-level stuff is even necessary to accomplish something the > compiler is perfectly able to do. > > From what I see, the reason for the hack is lack of > expressiveness: We don't have rvalue-refs in D (which I find > good) so, currently, there is no cast-solution as in C++. So for > a proper move() that works at CTFE, we'd need some specific tool. > > I have no idea of the details on how the compiler handles > lvalues. Would it make sense to add a compiler trait, > specifically to solve moving? Like __traits(move, > lvalue_expression) [name up for discussion] that is identical to > lvalue_expression with the exception that the (lvalue/rvalue) > flag (or whatever it is) is set to "rvalue". Basically, it's the > C++ solution: After the "cast", the compiler will proceed and > pretend it is an rvalue and therefore initiate moving. > > Do you think adding a trait to make move() and swap() work at > CTFE is worth it? > > A quick search showed me the class "Expression" has "virtual bool > isLvalue();" so it might be easy as wrapping and hooking that > virtual method. To me, [1] highly suggests that it works. > > [1] > https://github.com/dlang/dmd/blob/master/src/dmd/expression.d#L1219 I'm not sure that it really makes sense to worry about fixing stuff like this in CTFE before newCTFE is actually merged. For instance, as I understand it, current CTFE can't even really handle mutation. Rather, it creates a new value every time you mutate a variable. Don explained to me at one point about how even incrementing a variable allocates memory so that you then have a new value to use. Stuff like that is why CTFE is so slow and eats up so much memory. Much as it acts like it's running your code in a normal fashion, it's really not implemented that way (the reason that it works the way does having to do with how it grew into existence out of other features rather than being designed up front). The current CTFE implementation is incredibly hacky, and it's arguably a miracle that it can do as much as it can. newCTFE is taking a very different approach to CTFE, and in theory, it will fix many of the problems that CTFE currently has, but it's taking Stefan quite a while to get it to where it needs to be to actually merge it. - Jonathan M Davis
Constructing text with astericks
I've been given a challenge to write texts using asterisks to form the letters. D happen to have an unlimited amount of idioms yet i'm out out ideas as to the simplest approach. Task is to basically take a piece of text and write them as asterisks to the console. * * * * * * * * * * First solution I found was to create a class for each letter...like new A(), new B() and implement the logic withing each class. This doesn't scale and i'll have to write about 24 or more classes. Another complex but "makes sense" solution will be to use a GRID system like old digital watches but i'll need a more complex grid to draw complex letters using a dictionary of REPOPULATED indexes of asterisk for each word. First use the length of the string to compute the grid size and iterate over each character to indentify the dictionary of a letter's indexes to use: * *** ** ** *** ** *** ** *** (an R using a more complex Grid) How will you approach this problem in D idiomatically?
Re: Move and CTFE
On Wednesday, 30 May 2018 at 21:02:07 UTC, Jonathan M Davis wrote: On Wednesday, May 30, 2018 20:42:38 Q. Schroll via Digitalmars-d-learn wrote: It seems one cannot std.algorithm.mutation.move objects explicitly. Say I have a non-copyable type [...] It fails because move() cannot be executed at compile time. The reason "memcpy cannot be interpreted at compile time, because it has no available source code" sounds very suspicious. Why is it suspicious? memcpy is a C function, and you can't call C functions during CTFE precisely because the compiler doesn't have their source code. You can't call D functions either if the compiler doesn't have their source (e.g. if you're using a .di file to hide the implementation). I definitely do understand the error message and it makes sense that it fails the way it's implemented. However, it makes no sense that moving as a concept can fail at CTFE. That's what I find suspicious. [Maybe 'suspicious' isn't the right term; I couldn't express it better.] You can move rvalues at CTFE which proves that the compiler can do it. Shouldn't it be possible to move at CTFE, too, or does it mean, non-copyable types are practically unusable for CTFE? You can't do much in the way of pointer or memory manipulation during CTFE (e.g. no pointer arithmetic or reinterpret casts). So, I don't see how a move could be done during CTFE. Even if the source for memcpy were available during CTFE, I suspect that it wouldn't be allowed due to the lower level stuff that it does. That's the explanation why probably all currently possible library alternatives to memcpy would fail. I suspected that when encountering the error, but still wonder why memcpy or other low-level stuff is even necessary to accomplish something the compiler is perfectly able to do. From what I see, the reason for the hack is lack of expressiveness: We don't have rvalue-refs in D (which I find good) so, currently, there is no cast-solution as in C++. So for a proper move() that works at CTFE, we'd need some specific tool. I have no idea of the details on how the compiler handles lvalues. Would it make sense to add a compiler trait, specifically to solve moving? Like __traits(move, lvalue_expression) [name up for discussion] that is identical to lvalue_expression with the exception that the (lvalue/rvalue) flag (or whatever it is) is set to "rvalue". Basically, it's the C++ solution: After the "cast", the compiler will proceed and pretend it is an rvalue and therefore initiate moving. Do you think adding a trait to make move() and swap() work at CTFE is worth it? A quick search showed me the class "Expression" has "virtual bool isLvalue();" so it might be easy as wrapping and hooking that virtual method. To me, [1] highly suggests that it works. [1] https://github.com/dlang/dmd/blob/master/src/dmd/expression.d#L1219
Re: What's the purpose of the 'in' keyword ?
On 05/30/2018 03:16 PM, aberba wrote: On Sunday, 27 May 2018 at 16:00:15 UTC, Jonathan M Davis wrote: On Sunday, May 27, 2018 16:28:56 Russel Winder via Digitalmars-d-learn wrote: On Sun, 2018-05-27 at 13:10 +, Adam D. Ruppe via Digitalmars-d-learn - Jonathan M Davis Jonathan, which font were you using in your DConf powerpoint presentation for source code? It made the code look really nice...and also you have good naming skills. The pdf file has that information in it: http://www.identifont.com/similar?76H Ali
Re: What's the purpose of the 'in' keyword ?
On Sunday, 27 May 2018 at 16:00:15 UTC, Jonathan M Davis wrote: On Sunday, May 27, 2018 16:28:56 Russel Winder via Digitalmars-d-learn wrote: On Sun, 2018-05-27 at 13:10 +, Adam D. Ruppe via Digitalmars-d-learn - Jonathan M Davis Jonathan, which font were you using in your DConf powerpoint presentation for source code? It made the code look really nice...and also you have good naming skills.
Re: Setter chaining
The above idea can be emulated in code, abiet ugly and useless: https://dpaste.dzfl.pl/bd118bc1910c import std.stdio; struct CT(A,B) { A v; B t; alias v this; B opUnary(string s)() if (s == "~") { return t; } A opUnary(string s)() if (s == "*") { return v; } } class C { int q; CT!(int, typeof(this)) foo() { q = 3; CT!(int, typeof(this)) v; v.t = this; v.v = q; return v; } CT!(int, typeof(this)) bar(int y) { q = q + y; CT!(int, typeof(this)) v; v.t = this; v.v = q; return v; } } void main() { C c = new C(); auto x = *((~c.foo()).bar(6)); writeln(x); } With a language implementation, all one would need is a symbol, using #, everything would simplify to class C { int q; int foo() { q = 3; return q; } int bar(int y) { q = q + y; return q;} } auto x = c.#foo().bar(6);
Re: string file = __FILE__ considered harmful (and solution)
On Wednesday, 30 May 2018 at 14:40:50 UTC, Steven Schveighoffer wrote: On 5/30/18 4:27 AM, FeepingCreature wrote: There's a very common idiom where in order to report line numbers of an error or a log line at the callsite of a function, you pass __FILE__ and __LINE__ as default parameters: void foo(string file = __FILE__, size_t line = __LINE__); What's wrong with this? Say you add a string parameter, such as void foo(string msg, string file = __FILE__, size_t line = __LINE__); foo("Hello World"); Now when you accidentally grab an old version of the library, your new code will still run, but it will believe that it's being called from file "Hello World", line 15. Not good. Luckily there's a fix. Just stick this in some common header file in your project: struct CallerInfo { string file; size_t line; } void foo(string msg, CallerInfo caller = CallerInfo(__FILE__, __LINE__)); Now you cannot accidentally invoke foo with a string, or in fact any type except another instance of CallerInfo. Awesome idea! Unfortunately, it doesn't work. The __FILE__ and __LINE__ there are not from the caller, but from the line that defines foo. See here: https://run.dlang.io/is/siz9YZ https://run.dlang.io/is/oMe7KQ Less elegant, but solves the problem of accidental argument adding (CallerFile acts as a barrier). Unfortunately, while it works in theory, in practice the compiler crashes LOL
Re: no [] operator overload for type Chunks!(char[])
On Wednesday, 30 May 2018 at 21:27:44 UTC, Ali Çehreli wrote: On 05/30/2018 02:19 PM, Malte wrote: Why does this code complain at the last line about a missing [] operator overload? auto buffer = new char[6]; auto chunked = buffer.chunks(3); chunked[1][2] = '!'; Same happens with wchar. Dchar and byte work as expected. UTF-8 auto decoding strikes again. :) Even though the original container is char[], passing it through Phobos algorithms generated range of dchar. The thing is, those dchar elements are generated (decoded from chars) "on the fly" as one iterates over the range. Which means, there is no array of dchar to speak of, so there is no random access. Ali I see. Not what I would have expected, but makes sense for people working with UTF-8 strings. Thanks for the fast answer.
[Issue 18921] make core.internal.hash cater to memberwise hash chaining
https://issues.dlang.org/show_bug.cgi?id=18921 --- Comment #1 from Nathan S. --- Pull request: https://github.com/dlang/druntime/pull/2198 --
[Issue 18921] New: make core.internal.hash cater to memberwise hash chaining
https://issues.dlang.org/show_bug.cgi?id=18921 Issue ID: 18921 Summary: make core.internal.hash cater to memberwise hash chaining Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: enhancement Priority: P1 Component: druntime Assignee: nob...@puremagic.com Reporter: n8sh.second...@hotmail.com For use in memberwise hashing of structs (as in issue #18918) or in hashing arrays, speed up the hashing of individual scalars. Right now, for a `struct` where each field is `uint`, memberwise chained hashing has a 250% speed penalty with LDC2 and a 350% speed penalty on DMD2 compared to treating the struct as an array of bytes. This seems fairly constant regardless of the size of the struct. --
Re: no [] operator overload for type Chunks!(char[])
On 05/30/2018 02:19 PM, Malte wrote: Why does this code complain at the last line about a missing [] operator overload? auto buffer = new char[6]; auto chunked = buffer.chunks(3); chunked[1][2] = '!'; Same happens with wchar. Dchar and byte work as expected. UTF-8 auto decoding strikes again. :) Even though the original container is char[], passing it through Phobos algorithms generated range of dchar. The thing is, those dchar elements are generated (decoded from chars) "on the fly" as one iterates over the range. Which means, there is no array of dchar to speak of, so there is no random access. Ali
no [] operator overload for type Chunks!(char[])
Why does this code complain at the last line about a missing [] operator overload? auto buffer = new char[6]; auto chunked = buffer.chunks(3); chunked[1][2] = '!'; Same happens with wchar. Dchar and byte work as expected.
Re: Move and CTFE
On Wednesday, May 30, 2018 20:42:38 Q. Schroll via Digitalmars-d-learn wrote: > It seems one cannot std.algorithm.mutation.move objects > explicitly. Say I have a non-copyable type > > struct NoCopy > { > int payload; // some payload > pure nothrow @nogc @safe @disable: > this(this); // make it non copyable > } > > that is being used in a compile-time function evaluation where > values are being moved. > > int f() pure nothrow @nogc @safe > { > import std.algorithm.mutation : move; > NoCopy nc = NoCopy(1), nc2 = NoCopy(3); > nc = move(nc2); > return 0; > } > > static assert(f() == 0); // trigger CTFE > > It fails because move() cannot be executed at compile time. The > reason > "memcpy cannot be interpreted at compile time, because it has > no available source code" > sounds very suspicious. Why is it suspicious? memcpy is a C function, and you can't call C functions during CTFE precisely because the compiler doesn't have their source code. You can't call D functions either if the compiler doesn't have their source (e.g. if you're using a .di file to hide the implementation). > Shouldn't it be possible to move at CTFE, > too, or does it mean, non-copyable types are practically unusable > for CTFE? You can't do much in the way of pointer or memory manipulation during CTFE (e.g. no pointer arithmetic or reinterpret casts). So, I don't see how a move could be done during CTFE. Even if the source for memcpy were available during CTFE, I suspect that it wouldn't be allowed due to the lower level stuff that it does. Maybe the newCTFE stuff that Stefan is working on can do more in this area (I don't know), but in general, anything that's at all low-level is forbidden in CTFE. - Jonathan M Davis
Re: Proposal?
On Wed, May 30, 2018 at 03:34:55PM -0400, Steven Schveighoffer via Digitalmars-d wrote: > On 5/30/18 3:05 PM, Daniel N wrote: > > > void func(NONE...)(string s, NONE, string file = __FILE__, size_t > > line = __LINE__) if(!NONE.length) > > { > > import std.stdio; > > writefln("%s:%d: msg=%s", file, line, s); > > } > > > > void main() {func("hello"); func("there"); > > } > > Very cool and interesting pattern. [...] Note that this requires a recent version of DMDFE, because earlier versions are unable to handle additional arguments after a "..." parameter. T -- Why ask rhetorical questions? -- JC
Re: cycle dependencies
On Wednesday, 30 May 2018 at 18:49:40 UTC, Steven Schveighoffer wrote: On 5/30/18 11:50 AM, Stefan wrote: On Wednesday, 30 May 2018 at 13:26:53 UTC, Steven Schveighoffer wrote: On 5/30/18 8:09 AM, DigitalDesigns wrote: ... it's really really hard to make it check real dependencies. For serious dependency checking, you could try https://github.com/funkwerk/depend. It's used in quite large commercial projects. OK, so a couple things: 1. The cycle checking has to be really really fast, and run in a small amount of memory. It runs on startup of EVERY D program. I would LOVE to get rid of this problem, but unless we either invent our own object/linker system, or create some tools to work on the linked binary, we have to do this. 2. The cycle algorithm is fast and works correctly, given the dependencies that the compiler has provided. It's really not the cycle algorithm that is the problem, but the determination of dependencies. In other words, the problem is the compiler not tracing all the actual dependencies and outlining that in some structure to be parsed later during program startup. As you increase the number of dependency points, and therefore the graph size, the cycle algorithm has to take longer to figure out if there are any cycles. So even if we can fix the problem outlined here, the cost may not make it worth the effort! There are some ideas Martin and I have fleshed out a bit, which would help reduced the cyclic dependencies, but so far, nobody has had the time and/or skills to implement. For instance: https://issues.dlang.org/show_bug.cgi?id=16265 https://github.com/dlang/druntime/pull/1602#issuecomment-231527759 -Steve Why is this a runtime issue? It is not as if the execution of static this are non-deterministic. The compiler and linker must order the calls in some way. Maybe this is what you mean by own object/linker? But even then, they would only have to be checked once so why check every time the exe is ran when once it is ran it must remain statically oriented for all future. two exe's could be produced, one with only the static this code which is ran after linking and verified, if doesn't pass then a linker error is thrown. These methods could be used for better alternatives but the real issue is dependencies of static constructors. How bout instead require the user to deal with it? The user can specify the order to run and the compiler just blindly obeys. pragma(cycle, 1) static this() { } ... pragma(cycle, 2) static this() { } It could require cycle to be unique or just share and let the compiler do what it wants(assumes no cycles). This gives the programmer a fix but doesn't assume there are cycles, which most times there are not. Later on, more intelligent cycle detecting code can be created and added and then can give a warning in which the user can go back and add the pragmas. Alternatively, only require the pragmas on modules that cyclically import each other. Even if their is no cycle, the programmer just adds a pragma to satisfy the compiler/linker/rt.
[Issue 18920] core.internal.hash of array of scalars should be `@safe`
https://issues.dlang.org/show_bug.cgi?id=18920 --- Comment #1 from Nathan S. --- Pull request: https://github.com/dlang/druntime/pull/2197 --
[Issue 18920] New: core.internal.hash of array of scalars should be `@safe`
https://issues.dlang.org/show_bug.cgi?id=18920 Issue ID: 18920 Summary: core.internal.hash of array of scalars should be `@safe` Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: enhancement Priority: P1 Component: druntime Assignee: nob...@puremagic.com Reporter: n8sh.second...@hotmail.com Currently doesn't work: @safe unittest { import core.internal.hash : hashOf; const x = hashOf("abc"); } --
Re: Setter chaining
On Wednesday, 30 May 2018 at 15:46:36 UTC, Steven Schveighoffer wrote: On 5/30/18 10:49 AM, DigitalDesigns wrote: Does it sound good? class X { double x; @property X foo(double y) { x = y; return this; } @property X bar(double y) { x = y + 5; return this; } } void main() { X x = new X(); x.foo(3).bar(4); } It sort of emulates UFCS but I'm not sure if it's more trouble than it's worth. I figure it would be better than just returning void as it provides the option to chain but not sure if it will come back to bite me. Yes, I do this kind of stuff, but you need to word your functions correctly. I would avoid @property there, as this implies you should use it like: x.foo = 5; and if you return a reference to the type itself, it will read weird if you do it that way: auto five = (x.foo = 5); Here the name of the function is really really important. In my use case, I am kind of using it in an SQL builder type, where each time you call a method it adds some piece of the query. Like: auto query = table.select("id, name").where("foo = 5").orderBy("name"); -Steve Well, what I mean is to be able to have the ability to assign like a field or a function. sometimes I might want to use it as a property like x.foo = 5; and sometimes like a method x.foo(5).foo(8); for chaining. Rather than having to to create setfoo and such. Since D allows both syntaxes to be used, rather than returning void, turning parenting object allows the chaining to take place. Since the trick here is to be consistent, all setters must follow this principle, it shouldn't be a problem with consistency. auto five = (x.foo = 5); I wouldn't do that,just doesn't look right but I see your point. What would be cool is if D had some special way to return the object of the class the setter was in. auto x = (@x.foo = 5); Here @ returns x but first computes x.foo = 5;. In a way, it is like "this". @ gets the "this" of the function. Could work on any function: class Y { void foo(); @property int baz(); @property double bar(int x); } y.@foo() returns y; y.@baz() returns y; y.@bar(3) returns y; Essentially one could few all functions as returning this and the value in a tuple and be default the value is returned and using a "selector" character will return this. class Y { Tuple!(void, typeof(this)) foo(); Tuple!(int, typeof(this)) baz(); Tuple!(double, typeof(this)) bar(int x); } y.foo()[1] returns y; ... The compiler could simplify all this and by putting this in a register it could be be quite fast. In fact, since these are member functions and this is passed it will just fall through so very little overhead. The compiler can also optimize the code. Might take a bit to verify all the corner cases but would probably be useful once people could use it and get used to it. @, $, |, ?, ! or many symbols could be used without ambiguity because a dot will always preceded them.
Move and CTFE
It seems one cannot std.algorithm.mutation.move objects explicitly. Say I have a non-copyable type struct NoCopy { int payload; // some payload pure nothrow @nogc @safe @disable: this(this); // make it non copyable } that is being used in a compile-time function evaluation where values are being moved. int f() pure nothrow @nogc @safe { import std.algorithm.mutation : move; NoCopy nc = NoCopy(1), nc2 = NoCopy(3); nc = move(nc2); return 0; } static assert(f() == 0); // trigger CTFE It fails because move() cannot be executed at compile time. The reason "memcpy cannot be interpreted at compile time, because it has no available source code" sounds very suspicious. Shouldn't it be possible to move at CTFE, too, or does it mean, non-copyable types are practically unusable for CTFE?
Re: question about keeeping reference to toStringz()
On 05/30/2018 01:09 PM, Dr.No wrote: > consider a C function with this prototype: >> void foo(const char *baa); > > Does it means I should do: > >> string s = ...; >> auto cstring = s.toStringz; >> foo(cstring); > > rather just: > >> foo(s.toStringz); > > ? It depends. cstring method above is not sufficient if cstring's life is shorter than the C library's use: void bar() { string s = ...; auto cstring = s.toStringz; foo(cstring); } // <- cstring is gone What if the library saved that pointer while performing foo()? If cstring is in module-scope or in a container (e.g. an array) that's in module-scope then it's fine. But then, you would have to remove it from that container when the C library does not need that pointer anymore. Ali
Re: Proposal?
On Wednesday, 30 May 2018 at 19:34:55 UTC, Steven Schveighoffer wrote: On 5/30/18 3:05 PM, Daniel N wrote: void func(NONE...)(string s, NONE, string file = __FILE__, size_t line = __LINE__) if(!NONE.length) { import std.stdio; writefln("%s:%d: msg=%s", file, line, s); } void main() {func("hello"); func("there"); } Very cool and interesting pattern. If you now wanted to wrap the function (let's say the caller of this wants to forward it's own called file/line to it), you could do this as well: func!()("boo", file, line); Heh, didn't consider that use-case, cool indeed! How about we name the pattern "You shall not pass"/"None shall pass"? ;) I still think we should be able to wrap __FILE__ and __LINE__ into another call without having the wrapping take over the file/line combo. -Steve Agree, adheres to the Principle of least astonishment.
Re: string file = __FILE__ considered harmful (and solution)
On 05/30/2018 10:40 AM, Steven Schveighoffer wrote: But if we fixed the behavior that causes your idea not to work, then we could probably easily define a function like so: CallerInfo __CALLER__(string file = __FILE__, size_t line = __LINE__) { return CallerInfo(file, line); } Love it!
[Issue 18918] core.internal.hash should perform memberwise hashing of structs with references
https://issues.dlang.org/show_bug.cgi?id=18918 --- Comment #1 from Nathan S. --- Pull request: https://github.com/dlang/druntime/pull/2195 --
question about keeeping reference to toStringz()
The documentation says: Important Note: When passing a char* to a C function, and the C function keeps it around for any reason, make sure that you keep a reference to it in your D code. Otherwise, it may become invalid during a garbage collection cycle and cause a nasty bug when the C code tries to use it. (from https://dlang.org/library/std/string/to_stringz.html) consider a C function with this prototype: void foo(const char *baa); Does it means I should do: string s = ...; auto cstring = s.toStringz; foo(cstring); rather just: foo(s.toStringz); ?
Re: string file = __FILE__ considered harmful (and solution)
On 5/30/18 10:40 AM, Steven Schveighoffer wrote: But if we fixed the behavior that causes your idea not to work, then we could probably easily define a function like so: CallerInfo __CALLER__(string file = __FILE__, size_t line = __LINE__) { return CallerInfo(file, line); } Filed an issue so it's not forgotten: https://issues.dlang.org/show_bug.cgi?id=18919 -Steve
[Issue 18919] New: __FILE__ and __LINE__ should work when used in default argument expressions
https://issues.dlang.org/show_bug.cgi?id=18919 Issue ID: 18919 Summary: __FILE__ and __LINE__ should work when used in default argument expressions Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: enhancement Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: schvei...@yahoo.com Currently, __FILE__ and __LINE__ expand to the *caller's* location if used directly as default parameters in a function: void foo(string file = __FILE__, size_t line = __LINE__) { import std.stdio; writeln(file, " ", line); } void main() { foo(); // line 9 } prints "foo.d 9" But if you wrap those into an expression, it changes the meaning: struct Loc { string file; size_t line; } void foo(Loc loc = Loc(__FILE__, __LINE__)) // line 6 { import std.stdio; writeln(loc.file, " ", loc.line); } void main() { foo(); // line 14 } prints "foo.d 6" There's no reason it shouldn't just forward the original caller's file/line to the expression itself. It violates the principal of least surprise, and the current behavior is pretty near useless. In addition to fixing this, default parameters in expressions called should ALSO forward: Loc defaultLoc(string file = __FILE__, size_t line = __LINE) { return Loc(file, line); } void foo(Loc loc = defaultLoc) { writeln(loc.file, " ", loc.line); } This should print wherever foo is called from. I'd predict 0 code breakage, because anyone trying to use this would be wanting the expected behavior, so they wouldn't use this mechanism. --
[Issue 18918] New: core.internal.hash should perform memberwise hashing of structs with references
https://issues.dlang.org/show_bug.cgi?id=18918 Issue ID: 18918 Summary: core.internal.hash should perform memberwise hashing of structs with references Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: enhancement Priority: P1 Component: druntime Assignee: nob...@puremagic.com Reporter: n8sh.second...@hotmail.com So the following passes: ```d unittest { static struct S { char[] array; } auto s1 = S("abc".dup); auto s2 = S(s1.array.dup); import core.internal.hash : hashOf; assert(hashOf(s1) == hashOf(s2)); ``` The eventual goal is to make core.internal.hash usable as a replacement for `typeid(x).getHash()` that doesn't require runtime type info (useful for `betterC`) and doesn't ignore `const`-correctness. --
Re: Proposal?
On 5/30/18 3:05 PM, Daniel N wrote: void func(NONE...)(string s, NONE, string file = __FILE__, size_t line = __LINE__) if(!NONE.length) { import std.stdio; writefln("%s:%d: msg=%s", file, line, s); } void main() {func("hello"); func("there"); } Very cool and interesting pattern. If you now wanted to wrap the function (let's say the caller of this wants to forward it's own called file/line to it), you could do this as well: func!()("boo", file, line); I still think we should be able to wrap __FILE__ and __LINE__ into another call without having the wrapping take over the file/line combo. -Steve
[Issue 16208] moduleinfo importedModules contains needless duplicates
https://issues.dlang.org/show_bug.cgi?id=16208 --- Comment #4 from Steven Schveighoffer --- For archive purposes, on my system, that program prints: In module testcycle we import: In module core.bitop we import: core.cpuid core.cpuid In module core.cpuid we import: In module core.exception we import: In module core.runtime we import: In module core.thread we import: core.time In module core.time we import: In module core.internal.spinlock we import: core.thread In module gc.config we import: In module gc.gcinterface we import: In module gc.proxy we import: gc.impl.conservative.gc core.internal.spinlock In module gc.impl.conservative.gc we import: core.bitop core.thread core.time core.internal.spinlock core.internal.spinlock In module rt.critical_ we import: In module rt.deh_win64_posix we import: In module rt.dmain2 we import: In module rt.lifetime we import: rt.tlsgc core.bitop In module rt.minfo we import: core.bitop core.bitop core.bitop In module rt.monitor_ we import: In module rt.sections_osx_x86_64 we import: rt.minfo In module rt.tlsgc we import: rt.lifetime --
Re: Proposal?
On Wednesday, 30 May 2018 at 12:22:28 UTC, FeepingCreature wrote: On Wednesday, 30 May 2018 at 10:05:42 UTC, H. S. Teoh wrote: What about this? -- struct EndOfArgs { } EndOfArgs eoa; void func(string s, EndOfArgs _ = eoa, string file = __FILE__, size_t line = __LINE__) { import std.stdio; writefln("%s:%d: msg=%s", file, line, s); } void main() { func("hello"); func("there"); } -- Basically, use a dummy empty struct to differentiate between real arguments and context info. T Thank you, this seems to work well! We're using struct Fence { } Fence _ = Fence(), and it doesn't add much overhead. Barring the proposed compiler change, this seems the cleanest fix. void func(NONE...)(string s, NONE, string file = __FILE__, size_t line = __LINE__) if(!NONE.length) { import std.stdio; writefln("%s:%d: msg=%s", file, line, s); } void main() {func("hello"); func("there"); }
[Issue 16208] moduleinfo importedModules contains needless duplicates
https://issues.dlang.org/show_bug.cgi?id=16208 --- Comment #3 from Steven Schveighoffer --- Hm... any program has this problem. Example: import std.stdio; void main() { foreach(mi; ModuleInfo) { writeln("In module ", mi.name, " we import:"); foreach(imported; mi.importedModules) writeln(imported.name); } } --
Re: cycle dependencies
On 5/30/18 11:50 AM, Stefan wrote: On Wednesday, 30 May 2018 at 13:26:53 UTC, Steven Schveighoffer wrote: On 5/30/18 8:09 AM, DigitalDesigns wrote: ... it's really really hard to make it check real dependencies. For serious dependency checking, you could try https://github.com/funkwerk/depend. It's used in quite large commercial projects. OK, so a couple things: 1. The cycle checking has to be really really fast, and run in a small amount of memory. It runs on startup of EVERY D program. I would LOVE to get rid of this problem, but unless we either invent our own object/linker system, or create some tools to work on the linked binary, we have to do this. 2. The cycle algorithm is fast and works correctly, given the dependencies that the compiler has provided. It's really not the cycle algorithm that is the problem, but the determination of dependencies. In other words, the problem is the compiler not tracing all the actual dependencies and outlining that in some structure to be parsed later during program startup. As you increase the number of dependency points, and therefore the graph size, the cycle algorithm has to take longer to figure out if there are any cycles. So even if we can fix the problem outlined here, the cost may not make it worth the effort! There are some ideas Martin and I have fleshed out a bit, which would help reduced the cyclic dependencies, but so far, nobody has had the time and/or skills to implement. For instance: https://issues.dlang.org/show_bug.cgi?id=16265 https://github.com/dlang/druntime/pull/1602#issuecomment-231527759 -Steve
[Issue 16208] moduleinfo importedModules contains needless duplicates
https://issues.dlang.org/show_bug.cgi?id=16208 Mike Franklin changed: What|Removed |Added CC||slavo5...@yahoo.com --- Comment #2 from Mike Franklin --- Can you create a test case that demonstrates this problem? --
[Issue 18880] [REG2.079] Miscompilation of unittests when two are mixed-in on one line
https://issues.dlang.org/show_bug.cgi?id=18880 johanenge...@weka.io changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #5 from johanenge...@weka.io --- Yes, fixed by https://github.com/dlang/dmd/pull/8255 which adds a regression test for this bug. --
Re: cycle dependencies
On Wednesday, 30 May 2018 at 13:26:53 UTC, Steven Schveighoffer wrote: On 5/30/18 8:09 AM, DigitalDesigns wrote: ... it's really really hard to make it check real dependencies. For serious dependency checking, you could try https://github.com/funkwerk/depend. It's used in quite large commercial projects.
Re: Setter chaining
On 5/30/18 10:49 AM, DigitalDesigns wrote: Does it sound good? class X { double x; @property X foo(double y) { x = y; return this; } @property X bar(double y) { x = y + 5; return this; } } void main() { X x = new X(); x.foo(3).bar(4); } It sort of emulates UFCS but I'm not sure if it's more trouble than it's worth. I figure it would be better than just returning void as it provides the option to chain but not sure if it will come back to bite me. Yes, I do this kind of stuff, but you need to word your functions correctly. I would avoid @property there, as this implies you should use it like: x.foo = 5; and if you return a reference to the type itself, it will read weird if you do it that way: auto five = (x.foo = 5); Here the name of the function is really really important. In my use case, I am kind of using it in an SQL builder type, where each time you call a method it adds some piece of the query. Like: auto query = table.select("id, name").where("foo = 5").orderBy("name"); -Steve
[Issue 18917] Default Value for Function-Type Template Value-Parameter Causes Conflicts in Instantiation
https://issues.dlang.org/show_bug.cgi?id=18917 ZombineDev changed: What|Removed |Added Keywords||link-failure --
[Issue 18917] Default Value for Function-Type Template Value-Parameter Causes Conflicts in Instantiation
https://issues.dlang.org/show_bug.cgi?id=18917 ZombineDev changed: What|Removed |Added Keywords||rejects-valid CC||petar.p.ki...@gmail.com --
Re: What's the purpose of the 'in' keyword ?
On Sunday, 27 May 2018 at 16:00:15 UTC, Jonathan M Davis wrote: [...] Honestly, I'd suggest that folks never use in at this point. There's zero benefit to it. [...] Exactly. If you intend const, just write const. If you intend const scope, write const scope.
Setter chaining
Does it sound good? class X { double x; @property X foo(double y) { x = y; return this; } @property X bar(double y) { x = y + 5; return this; } } void main() { X x = new X(); x.foo(3).bar(4); } It sort of emulates UFCS but I'm not sure if it's more trouble than it's worth. I figure it would be better than just returning void as it provides the option to chain but not sure if it will come back to bite me.
Re: SOLUTION DOES NOT WORK
On 5/30/18 4:46 AM, FeepingCreature wrote: Updated subject to be visible at a glance. Note that a compiler-based solution via __CALLER__ would still work. I saw this after I replied. Oops :) I think it's a good idea, and I'm also believing that the issue that causes it not to work really could be addressed quite easily. -Steve
Re: string file = __FILE__ considered harmful (and solution)
On 5/30/18 4:27 AM, FeepingCreature wrote: There's a very common idiom where in order to report line numbers of an error or a log line at the callsite of a function, you pass __FILE__ and __LINE__ as default parameters: void foo(string file = __FILE__, size_t line = __LINE__); What's wrong with this? Say you add a string parameter, such as void foo(string msg, string file = __FILE__, size_t line = __LINE__); foo("Hello World"); Now when you accidentally grab an old version of the library, your new code will still run, but it will believe that it's being called from file "Hello World", line 15. Not good. Luckily there's a fix. Just stick this in some common header file in your project: struct CallerInfo { string file; size_t line; } void foo(string msg, CallerInfo caller = CallerInfo(__FILE__, __LINE__)); Now you cannot accidentally invoke foo with a string, or in fact any type except another instance of CallerInfo. Awesome idea! Unfortunately, it doesn't work. The __FILE__ and __LINE__ there are not from the caller, but from the line that defines foo. See here: https://run.dlang.io/is/siz9YZ At which point we can shorten this to CallerInfo caller = __CALLER__, and be forward compatible for additional information about the callsite, such as, say, attributes of the calling function. Hm.. I don't like this too much. Adding more magic to the compiler seems unnecessary. But if we fixed the behavior that causes your idea not to work, then we could probably easily define a function like so: CallerInfo __CALLER__(string file = __FILE__, size_t line = __LINE__) { return CallerInfo(file, line); } -Steve
Re: cycle dependencies
On 5/30/18 8:09 AM, DigitalDesigns wrote: Seriously stupid bug here! I had an enum an static this() { } (empty, forgot why I added it) one module and an struct in another module that converted values from the enum. I imported only that enum and guess what?!?! Cycle dependency! removed the static this() { } and worked! The cycle dependency checking code is far too ignorant. It is ignorant. It only checks for the presence of static constructors, not what they do. This is as designed -- there are too many ways for dependencies to leak between modules that it's really really hard to make it check real dependencies. It just blindly checks without any rationale. Someone said this was because phobos had a bug in it so the cycles were checked, maybe it's time to address that issue rather than breaking code arbitrarily? I don't know what was said, but the cycle code was very broken originally. A few years ago, I fixed it, and then it was re-broken by accident, and I re-fixed it. It should work properly now. But that has nothing to do with adding an empty static ctor, it had to do with properly detecting cycles. The cycle detection functions as designed. You can disable it via DRT flags, but this means that there is no guarantee that they run in the proper order. The compiler would have to build a much more sophisticated dependency tree in order to do anything more clever, but I doubt it would ever be able to be perfect in detecting which things truly depend on one another. -Steve
[Issue 16208] moduleinfo importedModules contains needless duplicates
https://issues.dlang.org/show_bug.cgi?id=16208 --- Comment #1 from github-bugzi...@puremagic.com --- Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/b60b669b4d92398f0fb770b895c2835a71c54e3f [Refactorization] Issue 16208 - curly braces on newlines https://github.com/dlang/dmd/commit/6d76646aaca6ccc8d633fea899a1e81b84e20533 Merge pull request #8311 from RazvanN7/Followup_16206 [Refactorization] Issue 16208 - curly braces on new lines --
Re: cycle dependencies
On Wednesday, 30 May 2018 at 12:09:21 UTC, DigitalDesigns wrote: Seriously stupid bug here! I had an enum an static this() { } (empty, forgot why I added it) one module and an struct in another module that converted values from the enum. I imported only that enum and guess what?!?! Cycle dependency! removed the static this() { } and worked! The cycle dependency checking code is far too ignorant. It just blindly checks without any rationale. Someone said this was because phobos had a bug in it so the cycles were checked, maybe it's time to address that issue rather than breaking code arbitrarily? I think an example would be useful. Anyway, if you think there's a bug there, write a report: https://issues.dlang.org Andrea
[Issue 18915] "Interface method not implemented" if interface reflects on implementing class
https://issues.dlang.org/show_bug.cgi?id=18915 Basile B. changed: What|Removed |Added CC||b2.t...@gmx.com Hardware|x86 |All OS|Windows |All --- Comment #1 from Basile B. --- Is this supposed to work or is this a wrong diagnostic (type B not yet finished when used in A) --
Re: Proposal?
On Wednesday, 30 May 2018 at 10:05:42 UTC, H. S. Teoh wrote: What about this? -- struct EndOfArgs { } EndOfArgs eoa; void func(string s, EndOfArgs _ = eoa, string file = __FILE__, size_t line = __LINE__) { import std.stdio; writefln("%s:%d: msg=%s", file, line, s); } void main() { func("hello"); func("there"); } -- Basically, use a dummy empty struct to differentiate between real arguments and context info. T Thank you, this seems to work well! We're using struct Fence { } Fence _ = Fence(), and it doesn't add much overhead. Barring the proposed compiler change, this seems the cleanest fix.
[Issue 18140] experimental allocators, bitmapped_block UB on OSX 64 bits
https://issues.dlang.org/show_bug.cgi?id=18140 Basile B. changed: What|Removed |Added Severity|normal |blocker --
[Issue 18914] std.experimental.allocator randomly fails on Darwin_64_64
https://issues.dlang.org/show_bug.cgi?id=18914 Basile B. changed: What|Removed |Added Status|NEW |RESOLVED CC||b2.t...@gmx.com Resolution|--- |DUPLICATE --- Comment #1 from Basile B. --- *** This issue has been marked as a duplicate of issue 18140 *** --
[Issue 18140] experimental allocators, bitmapped_block UB on OSX 64 bits
https://issues.dlang.org/show_bug.cgi?id=18140 Basile B. changed: What|Removed |Added CC||bugzi...@digitalmars.com --- Comment #2 from Basile B. --- *** Issue 18914 has been marked as a duplicate of this issue. *** --
Re: Build interface from abstract class
On Wednesday, 30 May 2018 at 10:31:27 UTC, Simen Kjærås wrote: On Monday, 28 May 2018 at 20:13:49 UTC, DigitalDesigns wrote: I do not think this is a problem in D. Infinite recursion can always be terminated with appropriate means. 1. Use attributes. methods in class A should be marked as being for the interface. When added to the interface they will not have the attribute so will not be picked up again. 2. Your method of function creation does not pick up attributes and other factors so it is weak. Here is my solution that does not solve problem 2: [Neat stuff] Neat, but as you say it doesn't handle attributes or UDAs. The use of stringof is also a red flag - the same name can apply to different types in different scopes, and aliases may confuse it. Here's a version that solves both of those issues: import std.array : join; import std.meta : ApplyLeft, staticMap, Filter, Alias; import std.traits; enum isPublic(alias overload) = Alias!(__traits(getProtection, overload) == "public"); interface InterfaceFromClass(T, alias filter = isPublic) { static foreach (overload; Filter!(filter, staticMap!(ApplyLeft!(MemberFunctionsTuple, T), __traits(derivedMembers, T mixin("@(__traits(getAttributes, overload)) "~attributes!overload~" ReturnType!overload "~__traits(identifier, overload)~"(Parameters!overload);"); } string attributes(alias overload)() { enum attrs = Filter!(ApplyLeft!(hasFunctionAttributes, overload), "pure", "nothrow", "ref", "@property", "@trusted", "@safe", "@nogc", "@system", "const", "immutable", "inout", "shared", "return", "scope"); return [attrs].join(" "); } alias A = InterfaceFromClass!C; abstract class C : A { int n; @("InterfaceMembers") { @(3) ref int foo(ref int a) { return n; } @(19) @safe void bar() { } } } // https://issues.dlang.org/show_bug.cgi?id=18915 // class D : C {} static assert([__traits(allMembers, A)] == ["foo", "bar"]); static assert(functionAttributes!(A.foo) == functionAttributes!(C.foo)); static assert(functionAttributes!(A.bar) == functionAttributes!(C.bar)); static assert(is(Parameters!(A.foo) == Parameters!(C.foo))); static assert(is(Parameters!(A.bar) == Parameters!(C.bar))); Note the link to issue 18915 (that's your 'string mixin output works...' post). I believe if we can fix that, the above should work. -- Simen Yeah! with a little work you can include fields in the interfacemembers because they will be ignored. I see no reason to have to declare an interface in D except in rare occasions! One should be able to abstract out an interface from a class or abstract class and use it as the base only for others to use. If a program was "sealed" there would be no real point in using interfaces(assuming it was designed to perfection) except to get around the diamond problem, which is what interfaces solve but in the process have forced us to duplicate code. The above technique alleviates that problem greatly. It's still bring the members inside the interface because it allows one to add final, static, and normal members if desired, although, this can be done by using another interface and inheriting from that.
cycle dependencies
Seriously stupid bug here! I had an enum an static this() { } (empty, forgot why I added it) one module and an struct in another module that converted values from the enum. I imported only that enum and guess what?!?! Cycle dependency! removed the static this() { } and worked! The cycle dependency checking code is far too ignorant. It just blindly checks without any rationale. Someone said this was because phobos had a bug in it so the cycles were checked, maybe it's time to address that issue rather than breaking code arbitrarily?
Re: string file = __FILE__ considered harmful (and solution)
On Wednesday, 30 May 2018 at 11:59:05 UTC, bauss wrote: On Wednesday, 30 May 2018 at 08:27:16 UTC, FeepingCreature wrote: There's a very common idiom where in order to report line numbers of an error or a log line at the callsite of a function, you pass __FILE__ and __LINE__ as default parameters: [...] void foo(string file = __FILE__, size_t line = __LINE__)(string msg); Wouldn't this solve it? No, because a) then you're completely pointlessly making a foo for every line it's called in, b) you're not future compatible with, say, call column, and c) you get exactly the same problem with template value parameters, ie. foo!"some ct argument".
Re: string file = __FILE__ considered harmful (and solution)
On Wednesday, 30 May 2018 at 08:27:16 UTC, FeepingCreature wrote: There's a very common idiom where in order to report line numbers of an error or a log line at the callsite of a function, you pass __FILE__ and __LINE__ as default parameters: [...] void foo(string file = __FILE__, size_t line = __LINE__)(string msg); Wouldn't this solve it?
[Issue 18916] ICE using Typedef and __LINE__
https://issues.dlang.org/show_bug.cgi?id=18916 Mike Franklin changed: What|Removed |Added Keywords||pull CC||slavo5...@yahoo.com --- Comment #1 from Mike Franklin --- Attempted Fix: https://github.com/dlang/dmd/pull/8310 --
Re: Build interface from abstract class
On Monday, 28 May 2018 at 20:13:49 UTC, DigitalDesigns wrote: I do not think this is a problem in D. Infinite recursion can always be terminated with appropriate means. 1. Use attributes. methods in class A should be marked as being for the interface. When added to the interface they will not have the attribute so will not be picked up again. 2. Your method of function creation does not pick up attributes and other factors so it is weak. Here is my solution that does not solve problem 2: [Neat stuff] Neat, but as you say it doesn't handle attributes or UDAs. The use of stringof is also a red flag - the same name can apply to different types in different scopes, and aliases may confuse it. Here's a version that solves both of those issues: import std.array : join; import std.meta : ApplyLeft, staticMap, Filter, Alias; import std.traits; enum isPublic(alias overload) = Alias!(__traits(getProtection, overload) == "public"); interface InterfaceFromClass(T, alias filter = isPublic) { static foreach (overload; Filter!(filter, staticMap!(ApplyLeft!(MemberFunctionsTuple, T), __traits(derivedMembers, T mixin("@(__traits(getAttributes, overload)) "~attributes!overload~" ReturnType!overload "~__traits(identifier, overload)~"(Parameters!overload);"); } string attributes(alias overload)() { enum attrs = Filter!(ApplyLeft!(hasFunctionAttributes, overload), "pure", "nothrow", "ref", "@property", "@trusted", "@safe", "@nogc", "@system", "const", "immutable", "inout", "shared", "return", "scope"); return [attrs].join(" "); } alias A = InterfaceFromClass!C; abstract class C : A { int n; @("InterfaceMembers") { @(3) ref int foo(ref int a) { return n; } @(19) @safe void bar() { } } } // https://issues.dlang.org/show_bug.cgi?id=18915 // class D : C {} static assert([__traits(allMembers, A)] == ["foo", "bar"]); static assert(functionAttributes!(A.foo) == functionAttributes!(C.foo)); static assert(functionAttributes!(A.bar) == functionAttributes!(C.bar)); static assert(is(Parameters!(A.foo) == Parameters!(C.foo))); static assert(is(Parameters!(A.bar) == Parameters!(C.bar))); Note the link to issue 18915 (that's your 'string mixin output works...' post). I believe if we can fix that, the above should work. -- Simen
[Issue 16206] traits getOverloads fails when one of the overload is a templatized function
https://issues.dlang.org/show_bug.cgi?id=16206 --- Comment #4 from github-bugzi...@puremagic.com --- Commits pushed to master at https://github.com/dlang/dlang.org https://github.com/dlang/dlang.org/commit/ee9cb9ba7c43a7401f222e0c1cb2063e0c35dd3b Fix Issue 16206 - traits getOverloads fails when one of the overload is a templatized function https://github.com/dlang/dlang.org/commit/0e3bd088a9e06e0873ea861d299026231217f644 Merge pull request #2351 from Biotronic/Issue16206 Fix Issue 16206 - traits getOverloads fails when one of the overload is a templatized function merged-on-behalf-of: Mike Franklin --
[Issue 16206] traits getOverloads fails when one of the overload is a templatized function
https://issues.dlang.org/show_bug.cgi?id=16206 --- Comment #3 from github-bugzi...@puremagic.com --- Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/b52561fc497b70380c2ecd8ebd92cf11c31f0a36 Fix issue 16206 - getOverloads fails when first overload is template https://github.com/dlang/dmd/commit/1ea020fcd22a8e1ee797328cba9f0c223dfba3bc Merge pull request #8195 from Biotronic/Issue16206 Fix Issue 16206 - traits getOverloads fails when one of the overload is a templatized function merged-on-behalf-of: unknown --
[Issue 18917] Default Value for Function-Type Template Value-Parameter Causes Conflicts in Instantiation
https://issues.dlang.org/show_bug.cgi?id=18917 Andrea Fontana changed: What|Removed |Added CC||trik...@gmail.com --- Comment #1 from Andrea Fontana --- Reduced: class A(T, T function(T) func = function(T a) { return a; }) { } void main() { A!char a; A!int b; } --
Re: Logging inside struct?
On Wednesday, 30 May 2018 at 10:07:35 UTC, Simen Kjærås wrote: On Wednesday, 30 May 2018 at 09:58:16 UTC, biocyberman wrote: [...] This line: writeln("got num: %s, of type: %s", num, typeof(num)); [...] Problem solved. Thanks Simen!
[Issue 18916] ICE using Typedef and __LINE__
https://issues.dlang.org/show_bug.cgi?id=18916 Basile B. changed: What|Removed |Added CC||b2.t...@gmx.com Hardware|x86_64 |All OS|Linux |All Severity|enhancement |major --
Re: Logging inside struct?
On Wednesday, 30 May 2018 at 09:58:16 UTC, biocyberman wrote: How do I add logging for this struct? https://run.dlang.io/is/9N6N4o If not possible, what's the alternative? This line: writeln("got num: %s, of type: %s", num, typeof(num)); Gives this error message: onlineapp.d(7): Error: cannot pass type int as a function argument The error message says exactly what's wrong - you can't pass a type as a runtime argument. You can get a string representation using .stringof: writeln("got num: %s, of type: %s", num, typeof(num).stringof); Next up: if prints this: got num: %s, of type: %s1int 1 You probably want something more like this: got num: 1, of type: int 1 The problem is you're using writeln, which only dumps its arguments to stdout in the order they're passed. writefln does formatting using %s: writefln("got num: %s, of type: %s", num, typeof(num).stringof); -- Simen
Re: Proposal?
What about this? -- struct EndOfArgs { } EndOfArgs eoa; void func(string s, EndOfArgs _ = eoa, string file = __FILE__, size_t line = __LINE__) { import std.stdio; writefln("%s:%d: msg=%s", file, line, s); } void main() { func("hello"); func("there"); } -- Basically, use a dummy empty struct to differentiate between real arguments and context info. T -- Don't drink and derive. Alcohol and algebra don't mix.
Logging inside struct?
How do I add logging for this struct? https://run.dlang.io/is/9N6N4o If not possible, what's the alternative?
Re: CMake support for D
On Tuesday, 27 February 2018 at 14:32:54 UTC, King_DuckZ wrote: ... My problem is mixing D with C and C++ ... you found already Dragos cmake-d, but not sure if you also know Dragos talk about mixing D with C/C++. If not, have a look: https://gitlab.com/dcarp/MUCplusplus/tree/master/2016.01.28
Re: Clash When Using Function as Template Value-Parameters?
On Tuesday, 29 May 2018 at 19:17:37 UTC, Vijay Nayar wrote: On Tuesday, 29 May 2018 at 12:58:20 UTC, Yuxuan Shui wrote: [...] I tried this again, this time completely ignoring lambdas and completely specifying the desired type like so: [...] Issue created: https://issues.dlang.org/show_bug.cgi?id=18917
[Issue 18917] New: Default Value for Function-Type Template Value-Parameter Causes Conflicts in Instantiation
https://issues.dlang.org/show_bug.cgi?id=18917 Issue ID: 18917 Summary: Default Value for Function-Type Template Value-Parameter Causes Conflicts in Instantiation Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: mad...@gmail.com Consider the following code snippet of a template class that has 3 paramters, the 3rd of which is a value-parameter with a function type and has a default value. ``` final class BTree( ValueT, KeyT = ValueT, const(KeyT) function(ValueT) nothrow pure @nogc KeyF = function KeyT(ValueT a) { return a; }) { KeyT getKey(ValueT val) { return KeyF(val); } } ``` When instantiating these templates, the first instantiation sets the value for the function value-parameter, and subsequent instantiations fail due to mismatching type. Example: ``` void main() { auto btree1 = new BTree!(char); auto btree2 = new BTree!(int); // The error is on this line. } ``` The error is: ``` onlineapp.d(17): Error: template instance `BTree!int` does not match template declaration `BTree(ValueT, KeyT = ValueT, const(char) function(char) pure nothrow @nogc KeyF = function KeyT(ValueT a) { return a; } )` ``` I believe that `BTree!(char)` and `BTree!(int)` should be recognized as different types at compile-time that have separate and distinct default values for the 3rd template-parameter. --
Proposal?
On Wednesday, 30 May 2018 at 08:27:16 UTC, FeepingCreature wrote: struct CallerInfo { string file; size_t line; } Let me try to flesh this out. void foo(CallContext caller = __CALL_CONTEXT__) { } // in druntime object.d struct CallContext { public size_t line; // expected to change for every call private const FunctionContext* functionContext; // expected to be constant for many calls alias functionContext this; } /** a variable with this type is lazily allocated once per function */ struct FunctionContext { string file, fileFullPath, module, function, prettyFunction; } I've looked at DMDFE and I don't think I know enough to do this, annoyingly.
[Issue 18916] New: ICE using Typedef and __LINE__
https://issues.dlang.org/show_bug.cgi?id=18916 Issue ID: 18916 Summary: ICE using Typedef and __LINE__ Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Severity: enhancement Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: trik...@gmail.com This code: import std.typecons: Typedef; alias Line = Typedef!int; void foo(Line line = __LINE__) { } void main(){ foo(); } On DMD: __LINE__ Illegal instruction (core dumped) On LDC2: Error: Internal compiler error: Type Expression not implemented: __LINE__ --
SOLUTION DOES NOT WORK
Updated subject to be visible at a glance. Note that a compiler-based solution via __CALLER__ would still work.
Re: string mixin output works when directly used but when generator is used D fails
On Tuesday, 29 May 2018 at 21:19:01 UTC, DigitalDesigns wrote: https://dpaste.dzfl.pl/67691db19ce8 Simplified: interface A { import std.meta : AliasSeq; alias a = AliasSeq!(__traits(getMember, B, "foo")); void foo(); } class B : A { void foo() { } } It seems the compiler is looking at the class before the interface is ready, and that the method thus isn't marked as implementing an interface method. Filed as https://issues.dlang.org/show_bug.cgi?id=18915 -- Simen
Re: string file = __FILE__ considered harmful (and solution)
Shit it doesn't work, I only checked if it compiled; it gives the wrong file/line number. NEVERMIND ALL
[Issue 18915] New: "Interface method not implemented" if interface reflects on implementing class
https://issues.dlang.org/show_bug.cgi?id=18915 Issue ID: 18915 Summary: "Interface method not implemented" if interface reflects on implementing class Product: D Version: D2 Hardware: x86 OS: Windows Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: simen.kja...@gmail.com interface A { import std.meta : AliasSeq; alias a = AliasSeq!(__traits(getMember, B, "foo")); void foo(); } class B : A { void foo() { } } Gives this error message: Error: class `B` interface function void foo() is not implemented --
Re: string file = __FILE__ considered harmful (and solution)
On 30/05/2018 8:27 PM, FeepingCreature wrote: There's a very common idiom where in order to report line numbers of an error or a log line at the callsite of a function, you pass __FILE__ and __LINE__ as default parameters: void foo(string file = __FILE__, size_t line = __LINE__); What's wrong with this? Say you add a string parameter, such as void foo(string msg, string file = __FILE__, size_t line = __LINE__); foo("Hello World"); Now when you accidentally grab an old version of the library, your new code will still run, but it will believe that it's being called from file "Hello World", line 15. Not good. Luckily there's a fix. Just stick this in some common header file in your project: struct CallerInfo { string file; size_t line; } void foo(string msg, CallerInfo caller = CallerInfo(__FILE__, __LINE__)); Now you cannot accidentally invoke foo with a string, or in fact any type except another instance of CallerInfo. This is such a basic type that it really belongs in phobos, arguably object.d. At which point we can shorten this to CallerInfo caller = __CALLER__, and be forward compatible for additional information about the callsite, such as, say, attributes of the calling function. ooo I have another solution. Use a named argument[0]! [0] https://github.com/rikkimax/DIPs/blob/named_args/DIPs/DIP1xxx-RC.md
string file = __FILE__ considered harmful (and solution)
There's a very common idiom where in order to report line numbers of an error or a log line at the callsite of a function, you pass __FILE__ and __LINE__ as default parameters: void foo(string file = __FILE__, size_t line = __LINE__); What's wrong with this? Say you add a string parameter, such as void foo(string msg, string file = __FILE__, size_t line = __LINE__); foo("Hello World"); Now when you accidentally grab an old version of the library, your new code will still run, but it will believe that it's being called from file "Hello World", line 15. Not good. Luckily there's a fix. Just stick this in some common header file in your project: struct CallerInfo { string file; size_t line; } void foo(string msg, CallerInfo caller = CallerInfo(__FILE__, __LINE__)); Now you cannot accidentally invoke foo with a string, or in fact any type except another instance of CallerInfo. This is such a basic type that it really belongs in phobos, arguably object.d. At which point we can shorten this to CallerInfo caller = __CALLER__, and be forward compatible for additional information about the callsite, such as, say, attributes of the calling function.
[Issue 18914] New: std.experimental.allocator randomly fails on Darwin_64_64
https://issues.dlang.org/show_bug.cgi?id=18914 Issue ID: 18914 Summary: std.experimental.allocator randomly fails on Darwin_64_64 Product: D Version: D2 Hardware: x86_64 OS: Mac OS X Status: NEW Severity: blocker Priority: P1 Component: phobos Assignee: nob...@puremagic.com Reporter: bugzi...@digitalmars.com It's a blocker because it randomly causes the autotester to fail, such as here: https://auto-tester.puremagic.com/show-run.ghtml?projectid=1=3185054=true The failing message: 0.066s PASS release64 std.experimental.allocator.building_blocks.allocator_list testAllocator failed for BitmappedBlock!(64LU, 8u, NullAllocator, cast(Flag)true) ** FAIL release64 std.experimental.allocator.building_blocks.bucketizer core.exception.AssertError@std/experimental/allocator/building_blocks/bitmapped_block.d(112): Data must be aligned properly ??:? _d_assert_msg [0x71d728e] ??:? pure nothrow ref @nogc std.experimental.allocator.building_blocks.bitmapped_block.BitmappedBlock!(64uL, 8u, std.experimental.allocator.building_blocks.null_allocator.NullAllocator, 1).BitmappedBlock std.experimental.allocator.building_blocks.bitmapped_block.BitmappedBlock!(64uL, 8u, std.experimental.allocator.building_blocks.null_allocator.NullAllocator, 1).BitmappedBlock.__mixin2.__ctor(ubyte[]) [0x6d880b7] ??:? pure nothrow @nogc std.experimental.allocator.building_blocks.bitmapped_block.BitmappedBlock!(64uL, 8u, std.experimental.allocator.building_blocks.null_allocator.NullAllocator, 1).BitmappedBlock std.experimental.allocator.building_blocks.bitmapped_block.BitmappedBlock!(64uL, 8u, std.experimental.allocator.gc_allocator.GCAllocator, 1).BitmappedBlock.__unittest_L1344_C17_1().__lambda2() [0x6d8a33f] ??:? void std.experimental.allocator.common.testAllocator!(std.experimental.allocator.building_blocks.bitmapped_block.BitmappedBlock!(64uL, 8u, std.experimental.allocator.gc_allocator.GCAllocator, 1).BitmappedBlock.__unittest_L1344_C17_1().__lambda2()).testAllocator() [0x6d89af6] ??:? void std.experimental.allocator.building_blocks.bitmapped_block.BitmappedBlock!(64uL, 8u, std.experimental.allocator.gc_allocator.GCAllocator, 1).BitmappedBlock.__unittest_L1344_C17_1() [0x6d86284] ??:? void std.experimental.allocator.building_blocks.bucketizer.__modtest() [0x6d81c38] ??:? void test_runner.doTest(object.ModuleInfo*, ref core.runtime.UnitTestResult) [0x5dde6d4] ??:? core.runtime.UnitTestResult test_runner.testModules() [0x5dde60b] ??:? core.runtime.UnitTestResult test_runner.tester() [0x5dde4df] ??:? runModuleUnitTests [0x71d7e0a] ??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() [0x71ec96c] ??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x71ec8f7] ??:? _d_run_main [0x71ec865] ??:? main [0x5dde383] ??:? start [0x5dde353] ??:? 0x0 [0x1] --
Re: CMake support for D
On Tuesday, 27 February 2018 at 14:32:54 UTC, King_DuckZ wrote: On Tuesday, 27 February 2018 at 09:20:21 UTC, Russel Winder wrote: [...] Right, I stand corrected about Rust, though as you say there are those who use it with CMake. About cmake-d, there's this https://github.com/dcarp/cmake-d/issues/19, which I could work around. More seriously though, it doesn't track dependencies between .d files. So if for example you have: [...] Are there any news at all about CMake support? Should I just give up?
Re: ost to pst convertes
EdbMails OST to PST Converter recovers corrupted OST file in to Outlook PST file. Which converts all the OST datfile into PST data file with all its attributes like Date & time, To, BCC, Subject, From, CC from corrupted OST file and also recovers Email body images, mails with all attachments, embed attachments etc. user can export OST files data to PST, EML, MSG formats. EdbMails OST to PST software also has Exclude / Include, Set after Date / Before Date and email Subject wise are filter options that can be used while exporting your OST to PST file. For more information visit: https://www.edbmails.com/pages/download-edb-to-pst-edb-to-office-365-edb-to-live-exchange-migrator.html