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
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: 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: 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
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
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&args=-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: Assert and undefined behavior
On Wednesday, 11 October 2017 at 09:39:04 UTC, user1234 wrote: On Wednesday, 11 October 2017 at 09:27:49 UTC, John Burton wrote: [...] I therefore feel like I ought to not use assert and should instead validate my assumptions with an if statement and a throw or exit or something. Yes, that's the way of doing. assert() are just used to test the program. the -release option in DMD disable all the assert() (excepted assert(0) which is a bit special), so that in a release version, only Throwable objects can be used after a failure detected. A small addition to the answers already provided. As user1234 has already said, asserts are removed in the -release build, so, if you have to validate some assumption (ex. the file opened) you should use enforce[0]. Cheers, Eduard [0] - https://dlang.org/library/std/exception/enforce.html
Re: 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.