Re: Debugging D code with GDB
On Tuesday, 30 November 2021 at 09:01:38 UTC, Iain Buclaw wrote: On Monday, 29 November 2021 at 14:48:21 UTC, Luís Ferreira wrote: [...] Indeed, gdb assumes calling convention is same as default for target (actually its been years since I last looked, but are calling conventions tags in dwarf? Does gdb know about functions with thiscall or regparm attributes?) Another thing on the gdb side, it is currently missing D language support for overloads, so that the correct function would be picked when you call e.g std.math.sin(1f). So currently the workaround is they way to go. Thank you all for your help and suggestions!
Debugging D code with GDB
I've started a thread on this problem on #Learn: https://forum.dlang.org/post/nmbmvzymsawzywpbt...@forum.dlang.org Your (the Debuggers community) input would be much appreciated. I'm referring the original post on the forum, as I'm hoping to keep all the answers in one place. This will help future searches by others like me. Thank you in advance, Edi
Debugging D code with GDB
Hello, I'm trying to use `gdb` to debug D binaries, but I'm having trouble accessing the methods of a struct or class. It seems that `gdb` doesn't see them. Given the following simple example ``` // test.d struct S { int x; void myPrint() { writefln("x is %s\n", x); } } void main(string[] args) { S s; } ``` Compile the source file with debug simbols (`dmd -g test.d -of=test`) and open the binary with gdb (`gdb test`) and run the following ``` break _Dmain # break at D entry point run ptype s type = struct test.S { int x; } print s.myPrint() Structure has no component named myPrint. ``` As you can see, when I try to access the `myPrint()` method I get the error "Structure has no component named myPrint." Looking up gdb's bugzilla, I've found this issue [0] that basically says that gdb treats D as C code (and that would explain why it doesn't look for function definitions inside D structs). A simple "fix"/"hack" to this problem is to define a helper function that will take my symbol as a parameter and internally call the function that I need, like below: ``` extern (C) void helper(ref S s) { s.myPrint(); } ``` While this does the job for this trivial example, it doesn't scale for a real project. Are there any solutions to this problem? Looking forward to your answers, Edi [0] - https://sourceware.org/bugzilla/show_bug.cgi?id=22480
Re: The Winners of the Last Two Prizes and Q & A Videos
On Sunday, 21 November 2021 at 20:48:30 UTC, Mike Parker wrote: […] Thank you everyone for an amazing dconf and for your talks. Looking forward to next year! Thank you Mike for MC-ing and for taking care of all the aspects surrounding the event. Thanks the DLF for the prizes!
Re: opOpAssign of AA: defined behavior?
On Tuesday, 23 June 2020 at 09:15:57 UTC, WebFreak001 wrote: [...] it will give me a range violation at runtime and not init it for me at all. There is `aa.require("a", Foo.init) += 4;` now which solves this, but I would prefer having the small simple syntax well defined for all types instead of only primitives. Also I don't see anywhere in the specification that `require` must actually return a ref value, so I can't trust this either. You make a very good case. I think this would make a great bootcamp issue (https://issues.dlang.org/) Cheers, Edi
Re: Telegram group for DLang
On Tuesday, 10 September 2019 at 19:56:20 UTC, Ernesto Castellotti wrote: On Monday, 9 September 2019 at 20:26:48 UTC, matheus wrote: On Thursday, 5 September 2019 at 08:13:14 UTC, Ernesto Castellotti wrote: I created a group on Telegram for DLang users, currently it is composed of about 10 people from the Italian community. Interesting, but do you mind if I ask what's wrong with IRC? Matheus. Difficult to answer, Telegram is a new platform, personally it is my favorite Generally the communities on Telegram are more welcoming and informal than IRC,however they are mostly subjective aspects Don’t get me wrong, but what about slack? I feel we have a lot of chats: irc, slack, discord, gitter, and now telegram :) Cheers to the new community, Edi
Re: Do I understand std.experimental.allocator composition correctly?
On Monday, 26 August 2019 at 01:06:55 UTC, James Blachly wrote: The documentation for std.experimental.allocator is a little dense and I wanted to make sure I am understanding composition correctly. [...] Yes, you are correct. Edi
Re: Exercism, call for mentors
On Tuesday, 20 August 2019 at 09:40:06 UTC, Björn Lindström wrote: Hello, I've recently decided to pick up D, and have started doing some exercises on https://exercism.io/ (a non-profit programming exercise platform), which I think is an excellent way to pick up the basics in a new language. While doing the exercises on my own is rewarding already, I would greatly appreciate if someone would want to pick up the mantle of mentor in D over there. Evidently someone liked the idea at one point enough to contribute D versions of a lot of the exercises, but based on progress of the queue, nobody is checking it frequently at the moment. I've been doing some mentoring there myself, for Python and Bash, and I think it's quite fun, and I learn a lot that way. It forces me to regularly think hard about the basics, trying to give considered advice to beginners. Anyway, if someone would be willing to give it a go, you can go to https://exercism.io/become-a-mentor and follow the instructions there. Thanks, Björn This is a great idea. I didn't know about https://exercism.io/ I've got a lot on my plate in the following weeks, but I'll try to make some time to mentor. I hope others in the community will join as well. Cheers, Edi
Re: Why in Phobos is empty() sometimes const and sometimes not
On Monday, 29 July 2019 at 17:32:58 UTC, Matt wrote: I've noticed that for some ranges in Phobos empty is marked const (e.g. iota) but for other ranges (e.g. multiwayMerge) it is not const. Is there a reason why? Isn't empty guaranteed not to alter the data of the range and so should be const? This is causing me considerable headaches as I try to write my own ranges that accept other ranges and have it all work for the general case. Any advice would be welcome. You could use introspection (a static i) to check if the type defines a const/non-const version and write the appropriate empty declaration. As for why it’s like this I’ll have to look at the code in Phobos, but I’m currently away from my pc (on the phone). Cheers, Edi
Building GDC with auto-generated header files
Cheers, everybody I'm working on this as part of my GSoC project [0]. I'm working on building gdc with the auto-generated `frontend.h` [1], but I'm having some issues There are functions in dmd that don't have an `extern (C)` or `extern (C++)` but they are used by gdc (are exposed in `.h` files) An example of such a function is `checkNonAssignmentArrayOp`[2] from `dmd/arrayop.d` which is can be found in `gcc/d/dmd/expression.h` [3] How does the linker find the right match in dmd? Since the function is `extern (D)`, isn't it mangled differently than C++? [0] - https://forum.dlang.org/thread/djurwumzfrrttvtdg...@forum.dlang.org [1] - https://github.com/dlang/dmd/pull/9971 [2] - https://github.com/dlang/dmd/blob/master/src/dmd/arrayop.d#L85 [3] - https://github.com/gcc-mirror/gcc/blob/master/gcc/d/dmd/expression.h#L84
Re: UPB D Summer School
On Wednesday, 17 July 2019 at 18:35:21 UTC, Meta wrote: On Wednesday, 17 July 2019 at 13:56:38 UTC, RazvanN wrote: [...] That's awesome! Did the students earn actual credit hours for this bootcamp, or was it more interest-based? The summer school was interest-based. There are quite a few cool summer schools organized at UPB, all interest-based, ranging from security (exploits, CTFs, etc.), networking and IoT to Android programming and ML. The great part: almost all of the students applying and attending those are also doing an internship for the summer, so we (organizers of summer schools) are competing to attract the best students and prove to them that their free, after work, time was well spent and they learned something cool, interesting and (most importantly) useful. We are very pleased with how the events took place and we're excited for an "encore"! Edi
Re: UPB D Summer School
On Wednesday, 17 July 2019 at 16:36:56 UTC, M.M. wrote: On Wednesday, 17 July 2019 at 13:56:38 UTC, RazvanN wrote: Hello, Edi and myself are glad to announce that the first edition of the D Summer School that we organized for the students at the University Politehnica of Bucharest has just ended. [...] Really nice! I actually think that D could be a nice language to be used for teaching programming. We also believe this and we hope that, sometime in the (near) future, we'll be able to introduce it in one of the 1st year courses I guess you had the summer school as an advanced topic? We had the summer school as an extracurricular course, after the summer finals. Our target audience was represented by, but not restricted to, 3rd year students that have prior experience with OOP languages (C++, Java, Python, etc.). We structured the sessions such that we'll cover as much of what D has to offer, starting from basic types and all the way to advanced meta-programming. From what we've observed, D has the key strength that even complex things such as template constraints and introspection are easy to grasp by a newcomer. Edi
Zero length arrays in D
Hello According to the spec[0], D supports zero length arrays [1]. I have given this a shot at https://run.dlang.io/is/PwbPxJ Attempting to use the zero-length array results in a compiler error `a.contents[2]` -> Error: array index 2 is out of bounds (*a).contents[0 .. 0] The way I've used around this error is "safely" break/trick the type system ``` int *p = a.contents.ptr; int[] p_cont = p[0 .. n]; p_cont[2] = 10; // fine ``` Is this the intended way of working with zero length arrays? Cheers, Edi [0] - https://dlang.org/spec/arrays.html#static-arrays, best practices pt 2 [1] - https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gcc/Zero-Length.html
Re: Is it possible to modify shared struct array in a function.
On Friday, 8 February 2019 at 06:55:15 UTC, Jerry wrote: On Friday, 8 February 2019 at 04:51:08 UTC, Sudhi wrote: On Friday, 8 February 2019 at 04:30:23 UTC, Arun Chandrasekaran wrote: On Friday, 8 February 2019 at 04:13:39 UTC, Sudhi wrote: [...] Works fine for me with DMD64 D Compiler v2.083.1. https://run.dlang.io/is/RRM8GU My example code was wrong. Below is the right one. struct Company { string name; string location; } struct Racks { int number; int location; } struct Metadata { string name; Company[] companies; Racks[] racks; } struct Item { Metadata[] met; int count; } shared (Item) item; void main() { updateMetadata(); } void updateMetadata() { Company company; company.name = "Hello"; company.location = "Bangalore"; item.met.companies ~= company; import std.stdio: writeln; writeln(item); } https://run.dlang.io/is/iem0PY You have to cast away shared: auto loc_item = cast(Item) item; loc_item.met ~= m; item = cast(shared) loc_item; Just to be clear, this is not threadsafe and require a mutex if you do this other than as init in main. You do not need to cast away shared. You had a couple of issues with your `updateMetadata()` function. First of, `met` is an array, so you need to index it: your code `item.met.companies ~= company` becomes `item.met[0].companies ~= company`. This will compile, but throw a range error because you don't have any `Metadata` object in your `met` array. I have typed below the revised form of your function ``` void updateMetadata() { // create a Company instance. This must be shared shared Company company; company.name = "Hello"; company.location = "Bangalore"; // create a shared Metadata instance shared Metadata m; m.name = "m"; // append m to the array of meta item.met ~= m; // append the company to the array of companies, for a given meta item.met[0].companies ~= company; import std.stdio: writeln; writeln(item); } ``` The working version is at https://run.dlang.io/is/RvRKrU Cheers, Edi
Re: std.container.rbtree as Interval Tree?
On Tuesday, 5 February 2019 at 19:12:43 UTC, James Blachly wrote: However, even when allowing (pseudo)duplicates, this means the distinct intervals with same start but different end coordinates are not deterministically placed/sorted within the tree, because they are not sortable with the simple `this.start < other.start` less function. I have updated the example with an `opCmp` implementation. https://run.dlang.io/is/ailnsy I believe this is what you are looking for. Cheers, Edi
Re: std.container.rbtree as Interval Tree?
On Monday, 4 February 2019 at 22:54:01 UTC, James Blachly wrote: I tried to implement an interval tree backed by std.container.rbtree today and fell flat. A standard way to make an interval tree is to make an augmented tree; I supposed since rbtree was a generic container and because I could define opCmp, this should be a cinch. I ran into two problems. First (minor problem), RedBlackTree considers a return value of 0 from opCmp equivalent to "equals", which is discordant with the guidance given for opCmp.[1] This is a minor pedantic point, since you cannot store un-orderable elements in the tree anyway. More importantly, though, I cannot figure out how to implement an interval query function on the tree. Typically, the tree would have a "key" that is the left position of the interval and the augmented part of the tree would be that a second value -- a right, or end, position. My Elem == key type is a struct encapsulating both of these (start, end; plus some metadata). For my Interval element type, I overloaded opCmp to take an integer, but unfortunately RedBlackTree's upperBound() and lowerBound() functions are defined in terms of "Elem" which is aliased to the contained element type, rather than a generic type. Q1: Is there a simple or elegant way to do this without re-implementing RedBlackTree? I apologize if it is obvious and I am missing it. I suppose it may work if I rewrite Interval's opCmp to not consider the upper bound, and by creating a dummy interval to pass to upperBound and lowerBound, but that seems inelegant compared to passing an integer. Q2: Would replacing "Elem" with a generic type "T" in the function signatures for upperBound, lowerBound, and various related fns like _firstGreater / _firstGreaterEqual solve this problem? James [1] https://dlang.org/spec/operatoroverloading.html#eqcmp ("For example ... x and y are disjoint sets, then neither x < y nor y < x holds, but that does not imply that x == y. Thus, it is insufficient to determine equality purely based on opCmp alone. ") I think you are making a slight confusion. Your `Interval` struct and the `Elem` type that `lowerBound` takes, are the same type. You can define your RBTree and Interval as follows ``` struct Interval { int start; int end; } alias IntervalTree = RedBlackTree!(Interval, (i1, i2) => i1.start < i2.start); ``` Please see this runable example: https://run.dlang.io/is/4cPTik The in-order traversal will be the same as the wikipedia example here: https://en.wikipedia.org/wiki/Interval_tree Hope this helps. Cheers, Edi
Re: __traits for checking if a type is dynamic array (slice)
On Monday, 26 November 2018 at 09:28:37 UTC, Basile B. wrote: On Monday, 26 November 2018 at 09:04:25 UTC, Per Nordlöw wrote: Why is there no - __traits(isArray, T) alongside - __traits(isStaticArray, T) and - __traits(isAssociativeArray, T) when dmd already has `ENUMTY.Tarray` alongside - ENUMTY.Tsarray and - ENUMTY.Taarray and std.traits already has a wrapper for this at https://dlang.org/phobos/std_traits.html#isDynamicArray ? Should we add this new builtin trait and use it in std.traits.isDynamicArray? If so, should we call it - __traits(isDynamicArray) or - __traits(isArray) or - __traits(isArraySlice) or - __traits(isSlice) or something else? Yeah maybe just try, although i see some alias this implication in the current std.traits implementation. Adding a new trait is rarely a big deal as far as i could see in the past (i.e no big never endings discussions). This would be a nice addition, imho. As Basile B is saying, there is quite a bit of work done for the `isDynamicArray` implementation. If you have the time to drill down from https://github.com/dlang/phobos/blob/master/std/traits.d#L6618 I was expecting the `isArray` check to be something like `enum isArray(T) = is(T == U[], U)` I would like to see this in the compiler traits :D
Re: Making external types available to mixins
On Sunday, 18 November 2018 at 11:29:51 UTC, John Chapman wrote: On Saturday, 17 November 2018 at 21:11:38 UTC, Adam D. Ruppe wrote: On Saturday, 17 November 2018 at 17:58:54 UTC, John Chapman wrote: Has anyone had a similar need and come up with a solution? You might be able to just pass it the Calendar type, and then fetch its parent module and get the ICalendarFactory from there (assuming they are defined in the same module). But generally speaking, passing strings to a mixin that refer to something in another module isn't going to work well thanks to scoping rules. You are better off passing a symbol of some sort. So there is no actual Calendar type. There's an ICalendarFactory type that creates instances of ICalendar (these types are part of a third-party API). "Calendar" is just a key users could use when calling a "makeWith" method that would build the ICalendar/Factory names, instantiate the factory, call the appropriate factory method and return the result. There are thousands of such object/factory pairs in the API. Just trying to cut out a lot of boilerplate code, but it doesn't seem doable this way. Cheers, So I had a go at this and I have a working solution. https://run.dlang.io/is/oaH6Ib At first, I tried to do everything in the mixin, as you can see with the `failedAttempt` function. The idea was that this should have worked like `mixin(failedAttempt!"Calendar"(1, 2, 3));`. As you can see, and the name suggests, I wasn't able to make it work with `args`. The solution I have to your problem is to use a template, in this case the `theType` template that will expand to the fully qualified name. So you'd use it like `makeWith!(theType!"Calendar")(args);` Hope it helps! Edi
Re: Built-in array opSliceAssign
On Thursday, 25 October 2018 at 21:00:46 UTC, Adam D. Ruppe wrote: On Thursday, 25 October 2018 at 19:56:18 UTC, Stanislav Blinov wrote: The current behavior of the compiler is quite the opposite of those "same as" above. Yeah, I guess I am maybe selectively reading the spec in light of the implementation... but I think the examples are just sloppy. Or maybe we have a buggy implementation but idk which is more useful. I still hold my believe that if opAssign is defined then that should be used. In my humble opinion, the current way might/could be faster, but it's not correct.
Re: Built-in array opSliceAssign
On Thursday, 25 October 2018 at 12:55:38 UTC, Adam D. Ruppe wrote: On Thursday, 25 October 2018 at 12:25:37 UTC, Eduard Staniloiu wrote: IMHO, this is a bug. The code should lower to calls to opAssing for types that define opAssign. The spec doesn't exactly say it uses memset, but it does imply it: https://dlang.org/spec/arrays.html#array-copying talking about "aggressive parallel code optimizations than possible with the serial semantics of C" and "copying" rather than "assigned" etc. but indeed postblit lets this work. You are right. Thank you! I guess I never read/understood it like this. I expected it to use opAssign as that is what's the most natural and intuitive decision for me. I take it that this is the expected behaviour, then.
Re: Built-in array opSliceAssign
On Thursday, 25 October 2018 at 13:01:06 UTC, Eduard Staniloiu wrote: On Thursday, 25 October 2018 at 12:38:44 UTC, Paul Backus wrote: On Thursday, 25 October 2018 at 12:25:37 UTC, Eduard Staniloiu wrote: As I wrote in the comments above, I was expecting `a[] = b[]` to iterate the slices and assign the elements of b into a. What really happens is a memcpy: as you can see from godblot [0], this gets lowered to a call to `_d_arraycopy`, in druntime. In D, when you assign one aggregate to another, opAssign is only called for the aggregate, not for any of its elements. However, postblit constructors are called for both. Example: https://run.dlang.io/is/XfDaWw Can you, please, give me a link to where it says this in the specs? Based on the example, I would expect that the code gets lowered to some version of `_d_arrayassign` [0]. I still think that this is problematic, as it's unexpected to the user: you're expecting the assignment operator to be called, not the postblit. I know that the compiler can and will create an opAssign if a postblit or dtor is defined, as you can write the assignment as a this._dtor; blit rhs into this. This being said, I think that if the user took the time to define opAssign, it should be called, because he might want to do something extra when an assignment occurs: an ex. having different logs "creating new obj" vs "changing existing obj". Your example will work as expected if you change the opAssign to a postblit constructor: https://run.dlang.io/is/HBbGO2 Accidentally sent to early. One extra reason as to why, imho, this implicit call to the postblit is evil, is that a lot of code will probably break when we'll transition to the CopyConstructor. See RazvanN's PR [0]. This is actually how I stumbled upon this, as I am using his branch with my repo. [0] - https://github.com/dlang/dmd/pull/8688
Re: Built-in array opSliceAssign
On Thursday, 25 October 2018 at 12:38:44 UTC, Paul Backus wrote: On Thursday, 25 October 2018 at 12:25:37 UTC, Eduard Staniloiu wrote: As I wrote in the comments above, I was expecting `a[] = b[]` to iterate the slices and assign the elements of b into a. What really happens is a memcpy: as you can see from godblot [0], this gets lowered to a call to `_d_arraycopy`, in druntime. In D, when you assign one aggregate to another, opAssign is only called for the aggregate, not for any of its elements. However, postblit constructors are called for both. Example: https://run.dlang.io/is/XfDaWw Can you, please, give me a link to where it says this in the specs? Based on the example, I would expect that the code gets lowered to some version of `_d_arrayassign` [0]. I still think that this is problematic, as it's unexpected to the user: you're expecting the assignment operator to be called, not the postblit. I know that the compiler can and will create an opAssign if a postblit or dtor is defined, as you can write the assignment as a this._dtor; blit rhs into this. This being said, I think that if the user took the time to define opAssign, it should be called, because he might want to do something extra when an assignment occurs: an ex. having different logs "creating new obj" vs "changing existing obj". Your example will work as expected if you change the opAssign to a postblit constructor: https://run.dlang.io/is/HBbGO2
Built-in array opSliceAssign
Hello, everyone! I have a question regarding the expected behaviour of the built-in array's opSliceAssign. Given the following code: ``` import std.stdio; struct A { int x; ref A opAssign(A rhs) { writefln("slice_bug.opAssign: begin"); return this; } } void main(string[] args) { A[] a = [A(1), A(2), A(3)]; A[] b = [A(2), A(3), A(4)]; // Expecting opAssign to be called for every element in a a[] = b[]; // In other words, I was under the impression that the above // is sintactic-sugar for for (size_t i = 0; i < a.lenght; ++i) { a[i] = b[i]; // This calls opAssign, as expected } } ``` As I wrote in the comments above, I was expecting `a[] = b[]` to iterate the slices and assign the elements of b into a. What really happens is a memcpy: as you can see from godblot [0], this gets lowered to a call to `_d_arraycopy`, in druntime. I'm not sure if this is the intended behaviour, though. I'm saying this as I've got bitten by this, because I'm doing reference counting inside opAssign. IMHO, this is a bug. The code should lower to calls to opAssing for types that define opAssign. I've also pasted the code on https://run.dlang.io/is/vneELO [0] - https://godbolt.org/z/_IXCAV
Ideas for students' summer projects
Hello, everyone! We, at UPB, have initiated D's participation to ROSEdu Summer of Code, see http://soc.rosedu.org/2018/. I will be mentoring a student over the summer and I was wondering if you have any suggestions for a project. If there is a library or feature that you would like just drop an idea. The proposed idea should be something that can be done in 8-10 weeks, though, ideally, we hope that the student/s will continue to contribute to the community after the summer ends. Let the brainstorming begin!
Re: NoCopy for overriding @disable this(this)
On Thursday, 12 April 2018 at 17:09:22 UTC, Shachar Shemesh wrote: On 12/04/18 18:42, Uknown wrote: On Thursday, 12 April 2018 at 12:16:53 UTC, Shachar Shemesh wrote: [...] The problem seems to be that cast is happening at compile time, as opposed to run time, as you might have already figured out. Do you need to really do this cast at compile time? I tried running the snippet you gave here: https://run.dlang.io/is/im19nL Is this how you intend for it to be used? Then there's no need for compile time casts. If not, could you give an example of how `NoCopy` would be used? struct Disabled { int i = 17; @disable this(this); } struct Container { NoCopy!Disabled disabled; } Any instance you create of "Container" will have i initialized to 0 by default. Since `T` has the postblit disabled, I'm guessing the ctor should take a `ref T`. Since `T` has the postblit disabled, I'm guessing the ctor should take a `ref T`.
Re: How to destruct class instances allocated by a Region-allocator over a single GC block
On Monday, 9 April 2018 at 14:51:24 UTC, Per Nordlöw wrote: On Monday, 9 April 2018 at 13:51:47 UTC, Steven Schveighoffer wrote: Well, you know the type, because make returned it no? The contract is, you call obj = make!X(args), then you have to call dispose(obj), where obj is of the type X. That's how it knows. If you are thinking you want to destroy the whole block at once (typed as void[]), that's not how it works. stdx.allocator is not going to help you with GC collection, it's not geared towards that purpose. Ok, thanks! If you are using a custom allocator to allocate memory then you also have to manually dispose of the memory when it is no longer needed. You can't have a custom allocator to supply you with the memory and then have the GC track and dispose of it. I get the feeling that this is what you were looking for?
Re: How to destruct class instances allocated by a Region-allocator over a single GC block
On Friday, 6 April 2018 at 21:49:37 UTC, Per Nordlöw wrote: On Tuesday, 3 April 2018 at 09:14:28 UTC, Eduard Staniloiu wrote: So, say `reg` is your allocator, your workflow would be auto obj = reg.make!Type(args); /* do stuff */ reg.dispose(obj); // If Type has a __dtor, it will call obj.__dtor // and then reg.deallocate(obj) If I do sucessive calls to reg.make!X where X are different kinds of classes of different sizes how does reg.dispose(obj) figure out at which address(es) (where emplace filled in the data) the objects reside? It can't figure out. With custom allocators you have to manually do the memory management, so the responsibility of when and which object needs to be destroyed falls on the user of the custom allocator.
Re: How to destruct class instances allocated by a Region-allocator over a single GC block
On Monday, 2 April 2018 at 21:32:47 UTC, Steven Schveighoffer wrote: On 4/2/18 5:16 PM, Per Nordlöw wrote: On Monday, 2 April 2018 at 20:43:01 UTC, Alexandru Jercaianu wrote: I am not completely sure how to solve this, but maybe we can find some clues here [1]. It seems like we should use addRoot on the buffer returned by GC.instance.allocate to keep it alive. Then, we can use addRange on each node after allocation and somehow use 'TypeInfo' to trigger destructors. I'll dig into this more tomorrow and come back with a better answer. How can there not be a documented answer for this question, given that std.experimental.allocator has been in Phobos for 2 years? Has std.experimental.allocator only been used for allocating `struct`s? Is the Region allocator especially misfit for constructing classes? Since a while, the GC also calls struct destructors, so it's likely to be a problem for both. Note, addRoot and addRange will NOT call the destructors appropriately. It will just prevent those memory areas from getting collected. The memory shouldn't be collected anyway because RegionAllocator should have a reference to it. The only way it will get destroyed is removing the root/range, and then it will get collected just like any other GC block -- same as it is now. It looks like std.experimental.allocator assumes you will manually destroy items (possibly via dispose), it has no mechanism to say "here's how to destroy this memory I'm allocating if you happen to collect it". -Steve The GCAllocator from std.experimental uses the druntime core.memory.GC, and allocates with a call to GC.malloc [1] The GC doesn't know how you are using the memory chunk that he provided you with. He only keeps a track of this chunk and will collect it when there are no more references to it; you could also manually free it, if you wish so, with a call to `GCAllocator.instance.deallocate`. As Steve has said, you will have to manually destroy the items. I recommend using dispose as it checks if the destroyed object has an explicit destructor, which it calls, before deallocating the memory. So, say `reg` is your allocator, your workflow would be auto obj = reg.make!Type(args); /* do stuff */ reg.dispose(obj); // If Type has a __dtor, it will call obj.__dtor // and then reg.deallocate(obj) Hope this helps. Cheers, Edi [1] - https://dlang.org/library/core/memory/gc.malloc.html
Re: Constructor qualifiers; bug or expected behavior?
On Monday, 2 April 2018 at 10:26:32 UTC, RazvanN wrote: Hi all, Let's say we have this code: struct B { int a; this(int a) immutable { this.a = 7; } this(int a) { this.a = 10; } } void main() { B a = immutable B(2); writeln(a.a); a.a = 4; type `B` immutable B a2 = immutable B(3); writeln(a2.a); a2.a = 3;// error : cannot modify } Both a and a2 will be constructed using the immutable constructor, however a is not immutable (a.a = 4 will compile fine). Is this the intended behavior? Shouldn't the compiler warn me that I'm trying to create a mutable object using the constructor for an immutable object? I couldn't find any documentation about this. The compiler does an implicit conversion from the type `immutable B` to the type `B`. It is able to do safely do so because `struct B` has only value types that can be copied. The same thing happens for immutable x = 1; int y = x; If you add an indirection in `struct B`, as such struct B { int a; int* p; /* ... */ } Then you can see that the implicit conversion fails with "onlineapp.d(22): Error: cannot implicitly convert expression B(0, null).this(2) of type immutable(B) to B" I put the code at https://run.dlang.io/gist/83756973012fcb4fec2660a39ffdad90=-unittest?args=-unittest The same conversion rules that apply to built in qualified types applies to structs. I'm guessing the same is for classes but I haven't played that much with those so a second opinion would be nice :) Cheers, Edi
Re: Postblit constructor
On Wednesday, 28 February 2018 at 18:27:49 UTC, Jiyan wrote: On Wednesday, 28 February 2018 at 18:23:04 UTC, Jiyan wrote: Hey, i thought i had understood postblit, but in my Code the following is happening (simplified): struct C { this(this){/*Do sth*/} list!C; void opAssign(const C c) { "Postlbit from C called".writeln; // Do sth } } Sry of course it is "Postlbit from C called".writeln; in this(this) and the c from opAssign should get constructed via postblit. Doesnt it? I'm not sure I understood your question, so please let me know if this clears things out or not. The parameter of opAssign will be constructed through a postblit call, but you need to explicitly assign what you want from the parameter inside the instance of _this_ object.
Re: Cannot make my shared PureMallocator callable in pure functions
On Saturday, 17 February 2018 at 12:33:25 UTC, Nordlöw wrote: I'm struggling with making https://github.com/nordlow/phobos-next/blob/master/src/pure_mallocator.d callable in pure functions such as here https://github.com/nordlow/phobos-next/blob/master/src/pure_mallocator.d#L84 Shouldn't a shared static shared PureMallocator instance; make it possible to call PureMallocator.instance.allocate(16); in pure functions? As the folks before me have pointed out, the language doesn't allow you to use globals inside pure code, excepting global immutables; this makes sense as once an immutable object was constructed it will never change. As Steven pointed out, we are just trying to fool the compiler into thinking that allocators don't have side effects; in the case of Mallocator, we are just forwarding calls to libc's mallocator. With this in mind, it looks to me that you just need to decide what is the best/easiest way for you to forward the calls. You could: 1) make all you methods static (after all, the allocator is stateless) 2) make `instance` immutable and make all the methods const
Re: Class allocators
On Saturday, 11 November 2017 at 14:26:34 UTC, Nordlöw wrote: Have anybody used allocators to construct class instances? I might be wrong, but I think you are looking for std.experimental.allocator.make [0] [0] - https://dlang.org/phobos/std_experimental_allocator.html#make
Re: Phobos' Windows Makefile
On Thursday, 12 October 2017 at 07:17:15 UTC, Jacob Carlborg wrote: On 2017-10-11 21:57, Eduard Staniloiu wrote: Hello, I've hit the following problem on this PR [0]: The Windows 32bit build fails with the error: "more than 32767 symbols in object file" [1]. After taking a look in `win32.mak`, I've seen that we are bundling multiple source files into a single object (which is the issue here), instead of compiling each source file into it's corresponding object and then linking the objects together. Is there a reason behind doing so, or should we rewrite the Windows makefiles? It's faster to compile when passing multiple files to the compiler at once. It doesn't have to run the compiler on the same files over and over again. I'm not convinced it's faster, as making a change in one of the bundled files will cause all the files in the object bundle to get recompiled, instead of compiling only the changed file and linking the objects.
Re: Assert and undefined behavior
On Wednesday, 11 October 2017 at 09:39:04 UTC, user1234 wrote: On Wednesday, 11 October 2017 at 09:27:49 UTC, John Burton wrote: [...] I therefore feel like I ought to not use assert and should instead validate my assumptions with an if statement and a throw or exit or something. Yes, that's the way of doing. assert() are just used to test the program. the -release option in DMD disable all the assert() (excepted assert(0) which is a bit special), so that in a release version, only Throwable objects can be used after a failure detected. A small addition to the answers already provided. As user1234 has already said, asserts are removed in the -release build, so, if you have to validate some assumption (ex. the file opened) you should use enforce[0]. Cheers, Eduard [0] - https://dlang.org/library/std/exception/enforce.html
Phobos' Windows Makefile
Hello, I've hit the following problem on this PR [0]: The Windows 32bit build fails with the error: "more than 32767 symbols in object file" [1]. After taking a look in `win32.mak`, I've seen that we are bundling multiple source files into a single object (which is the issue here), instead of compiling each source file into it's corresponding object and then linking the objects together. Is there a reason behind doing so, or should we rewrite the Windows makefiles? Looking forward to your answers! :) Cheers, Eduard [0] - https://github.com/dlang/phobos/pull/5331 [1] - https://auto-tester.puremagic.com/show-run.ghtml?projectid=1=2826646=true
Re: [OT] vim tip with column limits
On Monday, 9 October 2017 at 13:38:18 UTC, lithium iodate wrote: On Monday, 9 October 2017 at 00:24:02 UTC, Jonathan M Davis wrote: […] Thanks for the tip! You might also want to use automatic word wrapping [0] for 120 chars. Cheers, Eduard [0] - http://vim.wikia.com/wiki/Automatic_word_wrapping
Re: How do I filter out data from mongodb in D-code
On Tuesday, 10 October 2017 at 09:43:10 UTC, Anders S wrote: Hi, I'm working on a middleware application that reads array of data from a POSIX pipe and insert data into the db if any position in the array has changed. This is where my problem lays, in order not to duplicate data I want to fetch the latest data/document in the array of documents. I'm using MS Code and dub to code and compile. This is the code: Collection ct = mongo.boxweb.celltab; int i = 1; for(;i < 10; i++ ){ auto cell = ct.find({"number":i}).sort({_id:-1}).limit(2).pretty(); if (insert... i++; Where "number" is the document nr in the array I get these errors source/app.d(166,54): Error: found : when expecting ; following statement source/app.d(166,56): Error: found } when expecting ; following statement source/app.d(166,57): Error: found ) instead of statement dmd failed with exit code 1. Any ideas? Isn't there a way to markup code in the forum message to separate from the bodytext? /anders Hello, I haven't used mongo and D together, but by looking at [0] and [1] I can see that mondo is using Bson, which, as far as I can tell takes an associative array. I'm guessing you need to replace the JS dictionary sintax { k: v } with the AA one [ k: v ]. I haven't been able to try this out as I am on my phone. Also, this might be more suited for the Learn thread. Regarding the code markup, as far as I know, we don't have this. Hope this helps, Eduard [0] - https://code.dlang.org/packages/mondo [1] - http://vibed.org/api/vibe.data.bson/
Re: Deprecation message of library functions should state the replacement function
On Tuesday, 10 October 2017 at 13:56:36 UTC, Seb wrote: On Tuesday, 10 October 2017 at 12:57:36 UTC, bauss wrote: On Tuesday, 10 October 2017 at 11:48:48 UTC, Eduard Staniloiu wrote: Hi guys, I've just build druntime on Windows and we are displaying the following deprecation message: src\core\sys\windows\odbcinst.d(157): Deprecation: function core.sys.windows.odbcinst.SQLInstallTranslatorW is deprecated. I believe that we should also state with what should the deprecated function be replaced. My 2 cents, Eduard They usually do, I just assume it was forgotten there and if you know which function is to replace it, then simply create a pr? Or simply remove it as it has been deprecated since more than two years: https://github.com/dlang/druntime/blob/8fbcc2d819a84a5340cc6ac724320cae3561cb3b/src/core/sys/windows/odbcinst.d I'm not sure we should remove it since the replacement is available starting with ODBC 3.x [0]. I've made a PR [1] that states the replacement function in the deprecation message. [0] - https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlinstalltranslator-function [1] - https://github.com/dlang/druntime/pull/1936
Deprecation message of library functions should state the replacement function
Hi guys, I've just build druntime on Windows and we are displaying the following deprecation message: src\core\sys\windows\odbcinst.d(157): Deprecation: function core.sys.windows.odbcinst.SQLInstallTranslatorW is deprecated. I believe that we should also state with what should the deprecated function be replaced. My 2 cents, Eduard
Re: Why would an initialised struct pointer field be null in the struct's destructor?
On Saturday, 20 May 2017 at 10:48:54 UTC, Gary Willoughby wrote: Looks like you would want to use emplace [0] here. public this(int n) { this._data = (cast(Foo*) calloc(n, Foo.sizeof))[0 .. n]; foreach(ref element; this._data) { auto tmp = Foo(1); element = tmp; } } Cheers, Eduard [0] - https://dlang.org/phobos/std_conv.html#.emplace.3
Re: Missing functionality in std.process?
On Friday, 14 October 2016 at 16:33:51 UTC, Andre Pany wrote: What I miss is s.th. to get the child Pids of a parent Pid. Again I can use OS dependent functionality to retrieve the processIDs of the children, but how to convert these processIDs to Pids for usage with kill/wait functions? On Unix you could use core.sys.posix.signal.kill(pid_t, int) core.sys.posix.sys.wait.wait(int*) core.sys.posix.sys.wait.waitpid(pid_t, int*, int) I tested the kill function and it works like a charm. Since pid_t is just an alias to int, just provide the process integer to the function. On Windows, I'm guessing, you could use core.sys.windows.winbase.TerminateProcess(HANDLE, UINT) I don't have a Windows environment set up so you will have to play with this.
Re: Installing ldc breaks gdc
On Friday, 9 December 2016 at 17:53:30 UTC, Matthias Klumpp wrote: Hi! This issue should be fixed since LDC 1:1.1.0-2, which Xenial doesn't have. Ideally, fetch a newer version from Debian or a PPA to solve this issue. Cheers, Matthias Hi! Thank you for your answer. For future readers, this indeed has solved the problem. Just add the ppa: sudo add-apt-repository ppa:d-language-packagers/ppa And install the new version: sudo apt-get update; sudo apt-get install ldc Cheers, Eduard
Re: Installing ldc breaks gdc
On Friday, 9 December 2016 at 17:34:35 UTC, Daniel Kozak wrote: On Friday, 9 December 2016 at 17:34:35 UTC, Daniel Kozak wrote: No thats all wrong, dmd a gdc could not use same include directory that is not possible. GDC use /usr/lib/gcc/x86_64-linux-gnu/5/include/d/ Yes and no.. as you can see from the verbose output binary/usr/lib/gcc/x86_64-linux-gnu/5/cc1d version v2.067.1 parse gcd_bench importall gcd_bench import object (/usr/lib/gcc/x86_64-linux-gnu/5/include/d/object.d) importstd.algorithm (/usr/include/d/std/algorithm/package.d) import std.algorithm.comparison (/usr/include/d/std/algorithm/comparison.d) importstd.functional(/usr/include/d/std/functional.d) . . importstd.stdiobase (/usr/include/d/std/stdiobase.d) /usr/include/d/core/stdc/stdarg.d:48:5: error: undefined identifier __va_list_tag alias __va_list = __va_list_tag; ^ importcore.stdc.errno (/usr/include/d/core/stdc/errno.d) LDC use /usr/include/d/ binary/usr/bin/ldc2 version 0.17.1 (DMD v2.068.2, LLVM 3.8.0) config/etc/ldc2.conf contents of /etc/ldc2.conf: default: { // 'switches' holds array of string that are appends to the command line // arguments before they are parsed. switches = [ "-I/usr/include/d/ldc", "-I/usr/include/d", "-L-L/usr/lib", "-defaultlib=phobos2-ldc,druntime-ldc", "-debuglib=phobos2-ldc-debug,druntime-ldc-debug" ]; }; and dmd use: /usr/include/dmd binarydmd version v2.072.0 config/etc/dmd.conf contents of /etc/dmd.conf: [Environment32] DFLAGS=-I/usr/include/dmd/phobos -I/usr/include/dmd/druntime/import -L-L/usr/lib/i386-linux-gnu -L--export-dynamic [Environment64] DFLAGS=-I/usr/include/dmd/phobos -I/usr/include/dmd/druntime/import -L-L/usr/lib/x86_64-linux-gnu -L--export-dynamic You probably have some misconfiguration issue Everything is default, since they all have been installed with apt-get install
Installing ldc breaks gdc
Hello, everyone. So I have found that installing ldc will break gdc. The setup: I have a VM running a 64bit Ubuntu 16.04, as you can see from the output of uname -a: Linux ubuntu-xenial 4.4.0-51-generic #72-Ubuntu SMP Thu Nov 24 18:29:54 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux I have installed: dmd --version: DMD64 D Compiler v2.072.0 gdc --version: gdc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 With this setup, in /usr/include we can find dmd/ /usr/include/dmd |-- druntime | `-- import | |-- core | |-- etc As far as I can tell(guess), both dmd and gdc are using this one. I installed ldc2 (using apt-get install ldc): ldc2 --version: LDC - the LLVM D compiler (0.17.1): based on DMD v2.068.2 and LLVM 3.8.0 Default target: x86_64-pc-linux-gnu After installing ldc2, in /usr/include a new folder, d/, was created /usr/include/d |-- core |-- etc |-- ldc `-- std And now, the issue: After the steps above, when I try to compile something using gdc, it fails with the following error: /usr/include/d/core/stdc/stdarg.d:48:5: error: undefined identifier _va_list_tag alias __va_list = __va_list_tag; ^ Based on my previous assumtion (both dmd and gdc use /usr/include/dmd/) and the error above, I am inclined to believe that after installing ldc, gdc is using /usr/include/d/ and it breaks. Maybe we should consider having a separate folder in /usr/include/ for each compiler? Cheers, Eduard