Re: How to avoid variable capturing in `foreach` loop with lambdas?
On Thursday, 5 January 2023 at 22:49:01 UTC, thebluepandabear wrote: Have fun reading this : https://issues.dlang.org/show_bug.cgi?id=21929 Thanks for the code suggestion although it still doesn't fix the bug. I am curious as to what those brackets do as well. Okay, my bad for writing the wrong code, the correct one is: ```d foreach (BoardSize boardSizeIter; arr) (Boardsize boardSize){ // notice the brackets and I changed the variable names a little Button button = new Button(); button.text = format("%sx%s", boardSize[0], boardSize[1]); button.onButtonClick = { eventHandler.settingsWindow_onBoardSizeButtonClick(boardSize); }; button.onButtonClick(); _boardSizeRow.addChild(button); }(boardSizeIter) // notice the brackets and that I changed the name of you first foreach argument ``` This will do the same thing as HS Teoh and Tsbockman's code did : create a copy of the value that is currently present in one particular iteration of the `foreach` by creating a function literal that takes your `struct` as a paramter. This works because structs are value types, so passing it to the function creates a copy.
Re: How to avoid variable capturing in `foreach` loop with lambdas?
On Thursday, 5 January 2023 at 11:55:33 UTC, thebluepandabear wrote: I am using CSFML D bindings and I have created my own sort of UI library for drawing elements onto the screen. One of the classes I've created is a `Button` class, which contains a delegate called `onButtonClick` which is called when the button is clicked on by the user. Up until now, everything has worked fine. I want to add a couple of buttons side by side to represent an element of a list and assign them each a unique lambda expression for that particular element in the list, this is the current code I have: ```D foreach (BoardSize boardSize; arr) { Button button = new Button(); button.text = format("%sx%s", boardSize[0], boardSize[1]); button.onButtonClick = { eventHandler.settingsWindow_onBoardSizeButtonClick(boardSize); }; button.onButtonClick(); _boardSizeRow.addChild(button); } ``` Running this code, I had expected that everything would work fine. Unfortunately upon running the code, tapping each of the buttons returned only the largest `boardSize` value, the one which is gets iterated last. Note that I am still not totally sure why this is the case. At first, I was confused, but then I suspected that after the variable gets sent as a parameter to the `settingsWindow_onBoardSizeButtonClick` function, it gets changed again in the next iteration creating a sort of chain effect -- I may be wrong, but this is my suspicion. Some of the things I tried was creating a new object each time, although it didn't work. I might have not done this properly as I am a beginner to D language. I saw someone else ask a similar question as to why this is happening but that was for C#, not D, so it wasn't that much of a use to me. Help would be appreciated! Ah, I think you ran into that delegate bug # 🥲 Try this code in it's place: ```d foreach (BoardSize boardSize; arr) (){ // notice the brackets Button button = new Button(); button.text = format("%sx%s", boardSize[0], boardSize[1]); button.onButtonClick = { eventHandler.settingsWindow_onBoardSizeButtonClick(boardSize); }; button.onButtonClick(); _boardSizeRow.addChild(button); }() // notice the brackets ``` This is not your fault, it's an "optimization" that's being performed by dmd so that "the user doesn't get surprised" when they realize that capturing every single variable emitted in a `foreach` will allocate a new heap closure Have fun reading this : https://issues.dlang.org/show_bug.cgi?id=21929
Re: forgetting -betterC means no runtime bounds checking?
On Thursday, 5 January 2023 at 09:10:00 UTC, areYouSureAboutThat wrote: I was playing around with betterC, when I discovered, that if i accidently forget to provide -betterC to the compiler, it will still compile this, but, there will be no runtime bounds checking occuring. My question is: why is there no bounds checking occurring if I forget to use -betterC? module test; extern(C) void main() { import core.stdc.stdio : printf; int[5] arr = [ 0, 1, 2, 3, 4]; for (int i = 0; i < 10; i++) // oops! { printf("%d\n", arr[i]); } } Works on run.dlang.io for me: ```sh 0 1 2 3 4 dmd_runJFfSJW: onlineapp.d:12: Assertion 'array index out of bounds' failed. Error: program killed by signal 6 ``` On my personal ldc 1.27.1: ```sh (base) [tejasgarhewal@fedora ~]$ ldc2 -betterC -run ./D/oob.d 0 1 2 3 4 oob-06265c: ./D/oob.d:9: Assertion 'array overflow' failed. Error: /tmp/oob-06265c failed with status: -2 message: Aborted (core dumped) Error: program received signal 2 (Interrupt) (base) [tejasgarhewal@fedora ~]$ ```
Re: Can you simplify nested Indexed types?
On Tuesday, 27 December 2022 at 15:09:11 UTC, Sergei Nosov wrote: Consider, I have the following code: ``` auto a = [3, 6, 2, 1, 5, 4, 0]; auto indicies = iota(3); auto ai = indexed(a, indicies); ai = indexed(ai, iota(2)); writeln(ai); ``` Basically, my idea is to apply `indexed` to an array several times and have all the intermediaries saved in the same variable. The provided code doesn't compile with an error: ``` Error: cannot implicitly convert expression `indexed(ai, iota(2))` of type `Indexed!(Indexed!(int[], Result), Result)` to `Indexed!(int[], Result)` ``` I wonder, if there's a way to "collapse" or "simplify" the `Indexed!(Indexed!(int[], Result), Result)` type to just `Indexed!(int[], Result)` ? Well, pretty sure this isn't what you meant by "same variable" but since it _technically_ does what you want, I decided to share it: Basically I'm abusing `array` and this thing might be pretty memory heavy... ```d import std; void main() { auto a = [3, 6, 2, 1, 5, 4, 0]; auto indices = iota(3); auto ai = indexed(a, indices).array; ai = indexed(ai, iota(2)).array; writeln(ai); // [3, 6] } ```
Re: How to move from Unique(someClass) to Unique(someInterface)?
On Sunday, 27 November 2022 at 17:06:31 UTC, vushu wrote: On Saturday, 16 May 2020 at 17:45:56 UTC, Konstantin wrote: [...] I'm actually also very curious about this issue, since I come from c++ where this is possible, and it is a very common functionality for example for dependency inversion and dependency injection or mocking. It would be very nice to have this working. I _think_ it's not working here because `Unique` is a `struct`, so there's no concept of inheritance here, meanwhile that it possible in `C++`
Re: pointer escaping return scope bug?
On Friday, 25 November 2022 at 17:45:57 UTC, Paul Backus wrote: On Friday, 25 November 2022 at 14:07:28 UTC, ShadoLight wrote: On Saturday, 19 November 2022 at 15:00:16 UTC, Paul Backus wrote: Since, in your example, `lf` has global lifetime, the compiler deduces that `lf.fp` also has global lifetime, and therefore there is nothing wrong with assigning it to `p`. I follow your rationale, but for the life of me I cannot see how `lf` _"has global lifetime"_. You're right, my terminology here is sloppy. I'm really talking about the memory pointed to by `lf`, not `lf` itself, so I should really say that `lf` *points to memory* with global lifetime (or perhaps "`*lf` has global lifetime"). Time to use separation logic # 😈
Re: Is defining get/set methods for every field overkill?
On Wednesday, 23 November 2022 at 11:06:12 UTC, []() {}() wrote: On Wednesday, 23 November 2022 at 09:51:46 UTC, FeepingCreature wrote: Why then should a programming language insist that all other code in the module should be able to bypass my specification, and do as it pleases to my type? Please let's not repeat previous topics `private` will be enforced at module scope, for better or for worse, there has already been a [1000 post thread](https://forum.dlang.org/post/lqlllioynzfmpaozw...@forum.dlang.org) that resulted in basically nothing except someone creating a `private this` pull for curiosity that will never be accepted in the language Look at the very last post where the moderator had to externally kill the thread to prevent it from being revived/argued further
Re: Sorted Array (Container) Type
On Sunday, 13 November 2022 at 18:51:09 UTC, Siarhei Siamashka wrote: On Saturday, 12 November 2022 at 14:07:46 UTC, Per Nordlöw wrote: Have anybody created a wrapper container ```d struct Sorted(ArrayLike, alias lessThanPred) ``` that wraps an array-like type `ArrayLike` so that it's always sorted according to the binary predicate `lessThanPred`? I'm not sure if these are a good fit for what you need, but have you checked https://dlang.org/phobos/std_container_rbtree.html and https://dlang.org/phobos/std_container_binaryheap.html ? He said on Discord he want contiguous data structure, rbtree allocates too much
Re: dmd as a library
On Tuesday, 8 November 2022 at 00:05:18 UTC, vushu wrote: Any where to find learning material for using dmd as a library? thanks. https://github.com/Superbelko/dmdlib-notes This is the only resource I know of
Re: What's the correct way of creating an instance of class in D?
On Thursday, 3 November 2022 at 15:40:02 UTC, H. S. Teoh wrote: On Thu, Nov 03, 2022 at 04:41:14AM +, Siarhei Siamashka via Digitalmars-d-learn wrote: [...] ```D @safe: import std.stdio; class A { void foo() { writeln("foo"); } } void main() { auto a1 = new A; a1.foo(); // prints "foo" A a2; a2.foo(); // Segmentation fault } ``` [...] D does not have the equivalent of C++'s allocating a class instance on the stack. In D, all class instances are allocated on the heap and class variables are references to them. Declaring an instance of A as a local variable initializes it to the null reference, so invoking a method on it rightly segfaults. T I think his main problem will go away if the code just refuses to compile, since it's known at compile time that one is trying to dereference a `null` pointer Check my post, `A& a;` refuses to compile in C++20 atleast, asking to be explicitly initialized, thus averting the problem altogether
Re: What's the correct way of creating an instance of class in D?
On Thursday, 3 November 2022 at 04:41:14 UTC, Siarhei Siamashka wrote: C++ code: ```C++ #include class A { public: void foo() { std::cout << "foo" << std::endl; } }; int main() { auto a1 = new A; a1->foo(); // prints "foo" A a2; a2.foo(); // prints "foo" delete a1; } ``` D code: ```D @safe: import std.stdio; class A { void foo() { writeln("foo"); } } void main() { auto a1 = new A; a1.foo(); // prints "foo" A a2; a2.foo(); // Segmentation fault } ``` I didn't expect to see a segmentation fault in the code, which is a straightforward conversion from C++. And especially not with the use of the `@safe` attribute. What's going on here? ``` $ ldc2 --version LDC - the LLVM D compiler (1.30.0): based on DMD v2.100.1 and LLVM 14.0.6 built with LDC - the LLVM D compiler (1.30.0) Default target: x86_64-pc-linux-gnu ``` In D, all references and pointer types are default initialized to `null` no matter what, so you always have to explicitly assign an initial value if you dont want segfaults when dereferencing them ```d import std.stdio:writeln; void main(){ int* a; writeln(*a); // program killed by signal 11 int* b = new int(); writeln(*b); } ``` C++ initializes variable via the default constructor though, because it is a value type, like D's `struct`s ```cpp #include using namespace std; class A{ public: A(){ this -> a = new int(44); } int* a; }; int main() { int* a; cout << *a << "\n"; //prints any garbage value A instance; cout << *instance.a << "\n"; // always prints 44 return 0; } ``` Use a pointer, and you'll get the same undesirable behaviour ```cpp #include using namespace std; class A{ public: A(){ this -> a = new int(44); } int* a; }; int main() { int* a; cout << *a << "\n"; //prints any garbage value A* instance; cout << instance ->a << "\n"; // it's printing nothing for some reason return 0; } ``` You do get an error message if you use reference though, which D doesn't give even when using `@safe` C++: ```cpp #include using namespace std; class A{ public: A(){ this -> a = new int(44); } int* a; }; int main() { int* a; cout << *a << "\n"; //prints any garbage value A& instance; cout << instance.a << "\n"; // it's printing nothing for some reason return 0; } main.cpp: In function ‘int main()’: main.cpp:28:8: error: ‘instance’ declared as reference but not initialized 28 | A& instance; |^~~~ ``` D with `@safe`: ```d import std.stdio:writeln; void main() @safe { int* a; writeln(*a); // still segfault int* b = new int(); writeln(*b); } ``` # 😖
Re: Make IN Dlang
On Tuesday, 1 November 2022 at 23:40:22 UTC, Christian Köstlin wrote: Dear dlang-folk, one of the tools I always return to is rake (https://ruby.github.io/rake/). For those that do not know it, its a little like make in the sense that you describe your build as a graph of tasks with dependencies between them, but in contrast to make the definition is written in a normal programming language (in this case ruby) with all features of it. [...] Sounds pretty similar to [tup](https://gittup.org/tup/) Reggae, the build system mentioned by Adam, supports tup as a backend, so you could use that as well
Re: A strange DMD error
On Tuesday, 1 November 2022 at 15:49:54 UTC, Keivan Shah wrote: On Tuesday, 1 November 2022 at 15:42:43 UTC, Imperatorn wrote: On Tuesday, 1 November 2022 at 15:40:04 UTC, Keivan Shah wrote: Hello, Today I came across a strange bug while using D with `dmd`. I have still not been able to figure out under what conditions does it happen but it seems to be a DMD related bug to me. Here is a reproducible snippet of the code [...] Could be there's some restriction in DMD on number of arguments. May I ask if this was just an experiment? I hope you're not having code like that in the wild 🙏 Possible, but I think I have had code with more arguments than this and it has worked 😅 Unfortunately, not an experiment. Although have replaced the types so seems silly now, this is part of my constructor for a huge co-coordinator class that takes too many configurable start time parameters and so need to pass these many arguments. Keivan Regarding the too many configurable parameters, the general advice is to group all of the params into a `struct` and pass that instead as argument to constructor Pretty wild bug though, definitely a backend thing
Re: Find in assoc array then iterate
On Friday, 21 October 2022 at 22:03:53 UTC, Kevin Bailey wrote: I'm trying to do this equivalent C++: unordered_map map; for (auto i = map.find(something); i != map.end(); ++i) ...do something with i... in D, but obviously with an associative array. It seems that it's quite easy to iterate through the whole "map", but not start from the middle. Am I missing something obvious (or not so obvious) ? Maybe the following can help? ```d import std; void main(){ int[int] a = [2 : 4, 5 : 6, 6 : 7, 10 : 12, 11 : 23 ]; bool cont = true; foreach(k, v; a){ // use ref v instead of v if you wanna modify the values, like siarhei did in his post if (v != 7 && cont){ continue; } else{ cont = false; writeln(k, ":", v); } } /+ foreach(k, v; a.skipOver!((a, b) => a != b)(6)){ // this code could've worked if you had an inputRange, I think writeln(k, ":", v); } +/ } ```
Re: Detect uninitialized class var access
On Saturday, 24 September 2022 at 23:04:00 UTC, rassoc wrote: On 9/24/22 15:28, Adam D Ruppe via Digitalmars-d-learn wrote: gdb --args ./your_program and then it will tell you all the details you want to know about when this happens. Thank you for your input, Adam. Real shame that there's no built-in compiler solution and probably never will be according to [1]. :( D's competition got stuff like this right: ``` crystal build foo.cr In foo.cr:6:6 6 | puts f.x ^ Error: read before assignment to local variable 'f' ``` [1] https://issues.dlang.org/show_bug.cgi?id=4595 AFAIK diagnostics like that are not possible because Walter doesn't want to implement full blown dataflow analysis in the compiler since it will slow down the compilation speed of dmd
Re: Can you access the same classes from C++ and D and vise versa, or do the classes have to not form dependency cycle?
On Tuesday, 13 September 2022 at 03:13:59 UTC, Daniel Donnell, Jr wrote: On Sunday, 11 September 2022 at 02:14:51 UTC, zjh wrote: On Saturday, 10 September 2022 at 22:07:32 UTC, Ali Çehreli wrote: On 9/10/22 13:04, Daniel Donnell wrote: > https://dlang.org/spec/cpp_interface.html At DConf, Manu indicated that that page is outdated and that D's C++ support is actually a lot better. Update it quickly, This is a big selling point. So what is the answer here? I'm not sure what they were getting at... You can https://stackoverflow.com/a/53710273
Re: Constructors not working
On Friday, 2 September 2022 at 18:39:27 UTC, rikki cattermole wrote: I think you are wanting opAssign not opBinary. Also you made a mistake, since its a struct you don't want to new it when you construct and return it. ```d return new Time(secos / 3600, (secos % 3600) / 60, secos % 60); ``` Would be a ``Time*`` not ``Time`` which is what you returned. And shouldn't an `opAssign` be `void` anyways? Doubt there's many people writing stuff like `auto c = (a = b);`, where `a` is a `struct`/`class`.
Re: "Error: no property `offsetof` for type `char*`"
On Friday, 19 August 2022 at 16:36:24 UTC, MyNameHere wrote: On Friday, 19 August 2022 at 14:30:50 UTC, kinke wrote: Oh and `DevicePath()` is a convenience member returning a pointer to the 'dynamic array' (as the array decays to a pointer in C too), so no need to fiddle with `.offsetof` and computing the pointer manually. I am using ```-BetterC```, so that path is closed to me, I think. I believe you aren't allowed to _append_ to dynamic arrays/slices; otherwise you can use them
Re: Arbitrary precision decimal numbers
On Wednesday, 10 August 2022 at 14:11:04 UTC, Ruby The Roobster wrote: On Saturday, 6 August 2022 at 13:20:19 UTC, Sergey wrote: On Thursday, 4 August 2022 at 13:01:30 UTC, Ruby The Roobster wrote: Is there any implementation in phobos of something similar to BigInt but for non-integers as well? If there isn't is there a dub package that does this, and if so, which one? Also you could find usefull such projects: http://mir-algorithm.libmir.org/mir_bignum_decimal.html https://github.com/huntlabs/hunt-extra/blob/2d286f939193fc0cd55c799906f7657cec502dc8/source/hunt/math/BigDecimal.d It doesn't provide for arithmetic operations though, according to the docs. Maybe you'll have better luck with this? https://code.dlang.org/packages/gmp-d
Re: Python <==> d call both ways example (with PyD and autowrap)?
On Wednesday, 22 June 2022 at 16:02:00 UTC, mw wrote: Hi, I know with PyD, D can call Python, and with autowrap, Python can call a D .dll, I'm just wondering if someone can show an example that Python <==> d can call both ways? esp. show passing D objects to Python and then call its member function there, and vice versa. Thanks. IIRC the best you can do is embed a Python interpreter inside a D program https://pyd.readthedocs.io/en/latest/embed.html
Re: Better way to achieve the following
On Tuesday, 21 June 2022 at 17:09:28 UTC, JG wrote: Suppose we are often writing something like ```d theFirstName[theFirstIndex].theSecondName[theSecondIndex].thirdName[theThirdIndex]=x; ``` One would like to something like ```d alias shortName = theFirstName[theFirstIndex].theSecondName[theSecondIndex].thirdName[theThirdIndex]; shortName = x; ``` but you can't alias an expression. [...] Maybe check out `std.meta.Alias`? https://dlang.org/phobos/std_meta.html#.Alias
Re: UFCS limit
On Friday, 17 June 2022 at 01:04:28 UTC, Paul Backus wrote: Nope. The way UFCS works is that allows you to call free functions using member-function syntax, and member-function syntax is always `object.memberName`, so UFCS only works for functions that have a name, not anonymous functions. Would it be worthwhile to extend the scope of UFCS to accomodate this use case as well though??
Re: Can I create a package with friendly modules
On Sunday, 12 June 2022 at 05:05:46 UTC, forkit wrote: Is it possible to create a package.d, consisting of (for example), two modules, where each module can access private declarations within each other. In essence, declaring 'a module level friendship', or a kind of 'extended module' if you want. I might still want to add another module to the package, that is NOT part of that friendship between those other two modules, but is otherwise related to the solution. You can use `package(qualifiedIdentifier)` to satisfy this to a greater extent Directory structure: ```sh src | |--- main_file.d | |---parent | |--- driver.d | |--- package.d | |--- thing | |--- package.d | |--- first.d | |--- second.d | |--- third.d ``` Code : `src/main_file.d`: ```d import parent; void main() { func(); } ``` `src/parent/package.d`: ```d module parent; public import driver; ``` `src/parent/driver.d`: ```d module parent.driver; import thing; void func() { S s;// from third.d auto t = first.a; // from second.d auto l = second.dbl;// from first.d } ``` `src/parent/thing/package.d`: ```d module parent.thing; public import first, second, third; ``` `src/parent/thing/first.d`: ```d module thing.first; import second; static this() { a = second.g; // can also access symbols within neighbouring modules } package(parent): int a; int b; string c; ``` `src/parent/thing/second.d`: ```d module thing.second; package(parent): int g; char p; double dbl; ``` `src/parent/thing/third.d`: ```d module thing.third; package(parent): struct S { int a; char c; string s; } private S private_struct; // can't access via parent package, since marked private ``` You run it via: `dmd -i -I=./parent -I=./parent/thing main_file.d` (I'm pretty sure it'll look far prettier using `dub`) Here, all the symbols that are within package `thing` are visible to package `parent` as well, but not visible to any other package/module
Re: Error: cannot use non-constant CTFE pointer in an initializer `cast(immutable(char)*)TEST`
On Saturday, 11 June 2022 at 11:51:43 UTC, Tejas wrote: On Saturday, 11 June 2022 at 10:07:46 UTC, test123 wrote: how to work this around. ```d __gshared const TEST = import(`onlineapp.d`); extern(C) void main(){ __gshared bin_ptr = TEST.ptr; } ``` ```sh dmd2 -betterC -J. onlineapp.d onlineapp.d(3): Error: cannot use non-constant CTFE pointer in an initializer `cast(immutable(char)*)TEST` ``` Maybe try putting `__gshared bin_ptr = TEST.ptr;` inside a `shared static this(){}`? I mean, write it like: ```d __gshared bin_ptr; shared static this() { bin_ptr = TEST.ptr; } __gshared const TEST = import(`onlineapp.d`); extern(C) void main() { } ``` But `bin_ptr` becomes a global in this case :( Oh wait, `-betterC` is being used ;( hmm... Use [pragma(crt_constructor)](https://dlang.org/spec/pragma.html#crtctor) instead ```d __gshared immutable(char)* bin_ptr; pragma(crt_constructor) void init_ptr() { bin_ptr = TEST.ptr; } __gshared TEST = import("this.d"); extern(C) void main() { } ``` ```sh (base) [tejasgarhewal@fedora D]$ ldc2 -J. -betterC this.d (base) [tejasgarhewal@fedora D]$ ./this ```
Re: Error: cannot use non-constant CTFE pointer in an initializer `cast(immutable(char)*)TEST`
On Saturday, 11 June 2022 at 10:07:46 UTC, test123 wrote: how to work this around. ```d __gshared const TEST = import(`onlineapp.d`); extern(C) void main(){ __gshared bin_ptr = TEST.ptr; } ``` ```sh dmd2 -betterC -J. onlineapp.d onlineapp.d(3): Error: cannot use non-constant CTFE pointer in an initializer `cast(immutable(char)*)TEST` ``` Maybe try putting `__gshared bin_ptr = TEST.ptr;` inside a `shared static this(){}`? I mean, write it like: ```d __gshared bin_ptr; shared static this() { bin_ptr = TEST.ptr; } __gshared const TEST = import(`onlineapp.d`); extern(C) void main() { } ``` But `bin_ptr` becomes a global in this case :(
Re: Anybody have any idea on how to do shared operator overloads?
On Thursday, 2 June 2022 at 01:49:32 UTC, Ruby The Roobster wrote: On Thursday, 2 June 2022 at 01:29:39 UTC, Ruby The Roobster wrote: On Thursday, 2 June 2022 at 01:00:57 UTC, Ali Çehreli wrote: On 6/1/22 17:36, Ruby The Roobster wrote: > A stripped down version of some code I have: Not much experience here but I made two changes: 1) Added 'shared': > this(Complex!real num = Complex!real(0,0)) shared > { > this.num = num; > } > this(shared Complex!real num = cast(shared > Complex!real)Complex!real(0,0)) > { > this.num.re = num.re; > this.im.re = im.re; 2) Fixed apparent typos: this.num.im = num.im; > } I can't guarantee that correct functions are called. It just compiles with 2.100.0. :) Ali Yes, those were typos. However, when making this post, I forgot to mark ```this(shared Complex!real num = cast(shared Complex!real)Complex!real(0,0))``` as shared. The other constructor is not marked as shared in my code, considering as shared classes have all of their members marked as shared. I also have a bug: __traits(compiles) only checks if the expressions are SEMANTICALLY correct, not if they actually compile, which they don't. Interestingly, this code compiles between 2.063 and 2.066.1, if you were to put it into run.dlang.io, given the above changes (including the p1 + p2!), and set to all compilers. I fixed the typos and added some extra constructors and also wrote a little more complex `opBinary` for the `shared` overload of `Number`. Now the thing works(AFAICT): ```d public import std.complex; public import std.stdio; public interface Mtype { // ... } public class Number : Mtype { public: // new code begin this() { this.num = Complex!real(1,1); } this() shared { this.num = Complex!real(1,1); } // new code ends this(Complex!real num = Complex!real(0,0)) { this.num = num; } this(shared Complex!real num = cast(shared Complex!real)Complex!real(0,0)) shared { this.num.re = num.re; this.num.im = num.im; } Number opBinary(string op)(Number rhs) //Standard opBinary { mixin("return new Number(this.num " ~ op ~ " rhs.num);"); } shared(Number) opBinary(string op)(shared Number rhs) shared //changed this code a little as well { mixin(q{return new shared Number(Complex!real(this.num.re} ~ op ~ q{rhs.num.re, this.num.im} ~ op ~ q{rhs.num.im));}); //Placeholder untill I can get the code to work } package: Complex!real num; } bool isMtype(T)() { bool ret = true; // ... shared T p = new shared T(); shared T p2 = new shared T(); ret &= __traits(compiles, T, p + p2); return ret; } static assert(isMtype!Number); //This fails. Not anymore :D void main() { shared num1 = new shared Number(); shared num2 = new shared Number(); auto num3 = num1 + num2; writeln("real: ", num3.num.re, "\nimaginary: ",num3.num.im); } ```
Re: static assert("nothing")
On Tuesday, 31 May 2022 at 08:51:45 UTC, realhet wrote: Hi, In my framework I just found a dozen of compile time error handling like: ...else static assert("Invalid type"); This compiles without error. And it was useless for detecting errors because I forgot the first "false" or "0" parameter. I think it is because of the weird case of "every string casted to bool is true". There is an example in Phobos also: https://github.com/dlang/phobos/blob/master/std/uni/package.d at line 8847: static assert("Unknown normalization form "~norm); It is easy to make this mistake, but does static assert(string) has any meaningful use cases? This is what Zig does, actually: https://ziglang.org/documentation/0.9.1/#compileError ```Zig const std = @import("std"); const expect = std.testing.expect; test "comptime vars" { var x: i32 = 1; comptime var y: i32 = 1; x += 1; y += 1; try expect(x == 2); try expect(y == 2); if (y != 2) { // This compile error never triggers because y is a comptime variable, // and so `y != 2` is a comptime value, and this if is statically evaluated. @compileError("wrong y value"); } } ```
Re: gdc 12.1: undefined references when linking separately compiled files
On Saturday, 28 May 2022 at 13:12:46 UTC, kdevel wrote: I am trying to build a project with GDC. It successfully compiles with dmd and ldmd2. When I use gdc in one go the binary is successfully build: [...] Is seperate compilation working successfully for dmd and ldc? The only bug I know of regarding seperate compilation is https://issues.dlang.org/show_bug.cgi?id=20641
Re: Inferred attributes errors in template function.
On Friday, 27 May 2022 at 08:39:08 UTC, vit wrote: Hello, I have this problem: ```d static int i; void bar(T)(){ static if(is(T == int)) (()@system => 1)(); static if(is(T == float)) i = 42; } void foo(T)(){ bar!T(); } void main()@safe pure{ foo!long(); foo!float(); //Error: `pure` function `D main` cannot call impure function `onlineapp.foo!float.foo` foo!int(); //Error: `@safe` function `D main` cannot call `@system` function `onlineapp.foo!int.foo` } ``` When template function foo is called and its inferred attributes are not compatible with attributes of main, errors are not really useful. Compiler print that foo!float is not pure or foo!int is not @safe but doesn't tell why. Is in dmd some flag that print errors similarly to this?: ```d void main()@safe pure{ foo!long(); foo!float(); //Error: `pure` function `D main` cannot call impure function `onlineapp.foo!float.foo` //Error: potentially `pure` function `onlineapp.foo!float.foo` cannot call impure function `onlineapp.bar!float.bar` //Error: potentially `pure` function `onlineapp.bar!float.bar` cannot access mutable static data `i` foo!int(); //Error: `@safe` function `D main` cannot call `@system` function `onlineapp.foo!int.foo` //Error: potentially `@safe` function `onlineapp.foo!int.foo` cannot call `@system` function `onlineapp.bar!int.bar` //Error: potentially `@safe` function `onlineapp.bar!int.bar` cannot call `@system` delegate `onlineapp.bar!int.bar.__lambda1` } ``` Use `-verrors=context` for dmd ```d static int i; void bar(T)(){ static if(is(T == int)) (()@system => 1)(); static if(is(T == float)) i = 42; } void foo(T)(){ bar!T(); } void main()@safe pure{ foo!long(); foo!float(); /+ onlineapp.d(16): Error: `pure` function `D main` cannot call impure function `onlineapp.foo!float.foo` foo!float(); ^ +/ foo!int(); /+onlineapp.d(18): Error: `@safe` function `D main` cannot call `@system` function `onlineapp.foo!int.foo` foo!int(); ^ +/ } ```
Re: How to call destroy() in @nogc?
On Tuesday, 24 May 2022 at 02:29:38 UTC, cc wrote: ```d import core.memory; import core.stdc.stdlib : malloc, free; import core.lifetime : emplace; [...] FWIW your code will compile if you add `extern(C++)` to `Foo`
Re: UI Library
On Friday, 20 May 2022 at 02:37:48 UTC, harakim wrote: I need to write a piece of software to track and categorize some purchases. It's the kind of thing I could probably write in a couple of hours in C#/Java + html/css/javascript. However, something keeps drawing me to D and as this is a simple application, it would be a good one to get back in after almost a year hiatus. [...] Maybe gtkd? https://code.dlang.org/packages/gtk-d
Re: Unexplainable behaviour with direct struct assignment.
On Wednesday, 18 May 2022 at 21:52:18 UTC, HuskyNator wrote: On Wednesday, 18 May 2022 at 21:49:14 UTC, HuskyNator wrote: After updating to `DMD 2.100.0` & `DUB 1.29.0`, I still get this behavior. Only when I use `dub run --b=debug` however (default for me). `dub run --b=release` does return what one would expect. I don't know if this matters either, but I'm using windows 10 (64 bits). Does this happen with LDC as well?
Re: Language server
On Wednesday, 18 May 2022 at 01:04:16 UTC, Alain De Vos wrote: I tried neovim editor & serve-d and failed. I tried kate editor & serve-d and failed. https://github.com/Pure-D/serve-d Anyone has a clue ? I'm using [lunarvim](https://github.com/LunarVim/LunarVim). It provides you the ability to intall LSPs and treesitter parsers natively. Did you use `dub init` to create a project before trying to use `serve-d`? That could be why it doesn't work for you, maybe
Re: D WebAssembly working differently than C++, Zig
On Tuesday, 17 May 2022 at 09:38:31 UTC, Sergey wrote: On Monday, 16 May 2022 at 17:32:20 UTC, Allen Garvey wrote: I'm working on a comparison of WebAssembly performance for error propagation dithering using D, C++ and Zig. So far C++ and Zig work as expected, but for D, despite using the same algorithm and similar code the output is different. Hm D version is the slowest one?! It's faster than the JS version atleast. But yeah, C++ and Zig being 30+% faster than the D solution doesn't look good on us :(
Re: Why are structs and classes so different?
On Sunday, 15 May 2022 at 21:33:24 UTC, Ali Çehreli wrote: D programmers don't write move constructors or move assignment. Such concepts don't even exist. Never say never : https://github.com/dlang/DIPs/blob/master/DIPs/DIP1040.md Walter is one of the authors of the DIP Also, there's `opPostMove` already within the language
Re: Back to Basics at DConf?
On Friday, 13 May 2022 at 03:31:53 UTC, Ali Çehreli wrote: On 5/12/22 18:56, forkit wrote: > So...you want to do a talk that challenges D's complexity, by getting > back to basics? I wasn't thinking about challenging complexity but it gives me ideas. I am looking for concrete topics like templates, classes, ranges, rvalues, etc. Are those interesting? Ali DIP 1000 would be a good start :P Or a presentation on ranges can also be good, considering how the de facto best online article on it(by HS Teoh) is from 2013
Re: Back to Basics at DConf?
On Friday, 13 May 2022 at 04:19:26 UTC, Ola Fosheim Grøstad wrote: On Friday, 13 May 2022 at 03:31:53 UTC, Ali Çehreli wrote: On 5/12/22 18:56, forkit wrote: > So...you want to do a talk that challenges D's complexity, by getting > back to basics? I wasn't thinking about challenging complexity but it gives me ideas. I am looking for concrete topics like templates, classes, ranges, rvalues, etc. Are those interesting? I suggest: patterns for @nogc allocation and where D is going with move semantics and reference counting. Basically, where is D heading with @nogc? Take each pattern from c++ and Rust and show the D counter part, with an objective analysis that covers pitfalls and areas that need more work. I feel that it'd be best if any video discussion/talk about move semantics happens _after_ [DIP 1040](https://github.com/dlang/DIPs/blob/72f41cffe68ff1f2d4c033b5728ef37e282461dd/DIPs/DIP1040.md#initialization) is merged/rejected, so that the video doesn't become irrelevan after only a few years.
Re: What are (were) the most difficult parts of D?
On Thursday, 12 May 2022 at 15:18:34 UTC, jmh530 wrote: On Thursday, 12 May 2022 at 12:13:32 UTC, Basile B. wrote: [snip] ``` is ( Type : TypeSpecialization , TemplateParameterList ) is ( Type == TypeSpecialization , TemplateParameterList ) is ( Type Identifier : TypeSpecialization , TemplateParameterList ) is ( Type Identifier == TypeSpecialization , TemplateParameterList ) ``` I never remember those variants, because basically you never need them... They were required for std.traits and that's it. What's the difference between a Type and Type Identifier? `int`, `char` and friends are `Type` In `int a`, `string c`, `a` and `c` are `Identifier`s
Re: What are (were) the most difficult parts of D?
On Wednesday, 11 May 2022 at 14:20:07 UTC, H. S. Teoh wrote: On Wed, May 11, 2022 at 01:37:21PM +, matheus via Digitalmars-d-learn wrote: > [...] [...] [...] [...] My suggestion is: when prototyping, don't even think about attributes. Just templatize your functions and let the compiler infer the attributes for you. I myself rarely bother with attributes; I only write them when I want to be 100% sure that a particular piece of code has that attribute. Otherwise I just templatize it and let the compiler figure it out for me. Auto-inference is the way to go; life is too short to be fiddling with attributes in every single declaration manually. T That'll be true the day when `@safe` becomes the default... Until then, I'll atleast do `@safe:` on top of every module :)
Re: Parameters of overloaded templated function
On Tuesday, 10 May 2022 at 11:33:24 UTC, frame wrote: On Tuesday, 10 May 2022 at 11:26:44 UTC, frame wrote: On Tuesday, 10 May 2022 at 03:18:14 UTC, Tejas wrote: Can you try Makes no difference. OK, I tried it in separate test and works. Weird, I already tried that before, there must be something wrong with my other template. Thanks Using aliases as parameters doesn't work(and the DIP that wanted to have this behaviour was de facto rejected) https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1023.md But considering you're passing it as an argument, not a formal parameter, it should've worked... Idk what's happening there Try ```d alias getParams = Parameters!(typed);//add the parenthesis ``` _Maybe_ it's not taking the stuff after the second `!` when it substitutes the alias `typed`?
Re: Parameters of overloaded templated function
On Tuesday, 10 May 2022 at 01:00:24 UTC, frame wrote: So `__traits(getOverloads)` returns also templated members and `__traits(isTemplate)` can select those members. Unfortunately, `Parameters!` does not work with the templated member. How can I pass a symbol of T or A... to `Parameters!` as desired type without instantiating the template? ```d fun(T, A...)(T arg, string foo, int bar, A args); // some overload ``` Assuming T is just an `int`, I cannot apply this type. The compiler is forgetting the actual overload: ```d template getParams(alias overload) { static if (__traits(isTemplate, overload)) { alias typed = overload!int // error: fun(...) matches more than one template declaration alias getParams = Parameters!typed; } } ``` Can you try ```d template getParams(alias overload) { static if (__traits(isTemplate, overload)) { //alias typed = overload!int // error: fun(...) matches more than one template declaration alias getParams = Parameters!(overload!int); //don't use alias, send the argument directly } } ```
Re: Compile delegate with enum into proper function?
On Saturday, 7 May 2022 at 18:36:40 UTC, jmh530 wrote: In the code below, there is a two parameter function `foo` and an override of it with only one parameter. In the override case, I force the second one to be 1, but ideally there should be a way to specify it at compile-time. It would be kind of nice to be able to do it with an enum and a delegate or something, perhaps like `foo2`. However, that is still generating a delegate. Something like `foo3` also works, but I can't create that within a main function like I can for the delegate. I suppose the question is why can't I tell the compiler to compile a delegate into a proper function? I suppose this also holds for a function pointer. The difference I suppose is that the delegate with enums isn't really taking advantage of the features of a delegate, at least as far as I can tell. ```d int foo(int x, int a) { return x + a; } int foo(int x) { return x + 1; } enum int a = 1; auto foo2 = (int x) => {foo(x, a)}; int foo3(int x) { return x + a; } ``` ```d auto foo2 = (int x) => {foo(x, a)}; ``` Why did you use the `{ }` when you already used `=>`??? The following code compiles `foo2` as a function ```d int foo(int x, int a) @nogc { return x + a; } int foo(int x) { return x + 1; } enum int a = 1; auto foo2 = (int x) @nogc => foo(x, a); int foo3(int x) { return x + a; } void main()@nogc { foo2(5); pragma(msg, typeof(foo2)); //int function(int x) @nogc @system } ``` I still recommend using my default argument values solution though if it is feasible.
Re: Compile delegate with enum into proper function?
On Sunday, 8 May 2022 at 01:38:55 UTC, jmh530 wrote: On Saturday, 7 May 2022 at 23:30:37 UTC, Paul Backus wrote: [snip] Worth noting that you *can* write ```d alias foo = partial!(foo, a); ``` ...which will add the partially-applied version to `foo`'s overload set. You sure about that? Below fails to compile on godbolt with ldc 1.27.1 [1]. For some reason run.dlang.org is just hanging... ```d import core.stdc.stdio: printf; import std: partial; int foo(int x, int a) { return x + a; } enum int a = 2; alias foo = partial!(foo, a); void main() { int x = 2; int y = foo(x, a); printf("the value of y is %i", y); auto z = foo(x); printf("the value of z is %i", z); } ``` [1] https://d.godbolt.org/z/dx8aWfjYW If there is only one possible value for the overload, is there an issue with using default arguments? ```d int foo(int x, int a = 1) { return x + a; } void main() { import std.stdio:writeln; writeln(foo(5)); writeln(foo(6, 7)); } ```
Re: Google Code Jam 2022
On Friday, 6 May 2022 at 08:25:34 UTC, Siarhei Siamashka wrote: On Friday, 6 May 2022 at 07:05:35 UTC, zjh wrote: For example, I think `d` can also make use of `'winrt'`, which is very important for `GUI` programming . `D` officials should pay attention to `it`. I have downloaded `dwinrt` and has many compilation errors! Regularly introducing compatibility breaking changes in the language and effectively pulling the rug from under the developer's feet can make maintaining a medium or large project rather expensive. And I guess, a lot of people hesitate to use D language in production because of this reason. The old code bitrots and stops compiling. Not everyone is ready to pay this tax. Long term maintenance is just much cheaper when using the other programming languages. But again, programming competitions are all about just writing quick and dirty disposable code. If my solution submitted in a programming contest is going to stop compiling by a future version of the compiler, then I couldn't care less. So one of the major D language disadvantages has no real impact on its suitability for programming competitions. At least in theory. But maybe I'm missing something? Maybe the languages being chosen simply reflect the status quo? A lot of people participate to get job offers, not because they're enthusiastic about CP itself, so they just use the language they're looking to get a job in/think has the highest job prospects. Sure, they can use a more fringe language, but why bother? There'll be extra time and effort involved in learning how to do stuff with that language, resources that could have been better spent becoming better at the mainstream language instead, which they might have to do anyways since those are the languages that they'll actually use at the job. I don't think they have any incentive to use non- mainstream languages(atleast those that are just in it to get the job), that time is better spent on practicing more problems/reading someone else's solution(which would also most likely be in C++/Python/JavaScript/etc...) This is why I don't think there's any reason to believe that CP participants will use a fringe language in competitions.
Re: How to use destroy and free.
On Tuesday, 3 May 2022 at 12:59:31 UTC, Alain De Vos wrote: Error: array literal in @nogc function test.myfun may cause a GC allocation @nogc void myfun(){ scope int[] i=[1,2,3]; }//myfun May is a fuzzy word... For this particular piece of code, you can use a static array to guarantee the usage of stack allocation ```d import std; @nogc void myfun(){ /* no need to use scope now */int[3] i=[1,2,3];//this now compiles }//myfun void main() { writeln("Hello D"); } ```
Re: Parameters declared as the alias of a template won't accept the arguments of the same type.
On Tuesday, 3 May 2022 at 00:38:34 UTC, Tejas wrote: On Monday, 2 May 2022 at 22:01:51 UTC, ag0aep6g wrote: On 02.05.22 22:47, Stanislav Blinov wrote: On Monday, 2 May 2022 at 20:16:04 UTC, ag0aep6g wrote: On 02.05.22 21:17, Stanislav Blinov wrote: On Monday, 2 May 2022 at 16:29:05 UTC, Loara wrote: [...] ```d template MyAlias(T){ alias MyAlias = int; } T simp(T)(MyAlias!T val){ return T.init; } int main(){ simp(3);//Impossible to deduce T [...] That's not my answer. And it is nonsense, because my answer is - what T is irrelevant, MyAlias maps *all* types to int. Therefore `simp` takes an int, which is what the caller is passing. And what does it return? Perhaps one way could be to assume that the parameter passed is of type `aliasTemplate!typeOfVar` and see if it helps make sense of the invocation? This would only be done if the parameter's type doesn't directly match the required type nor it is implicitly convertible to it(which can be further constrained by... constraints...) For example, here: ```d template MyAlias(T){ alias MyAlias = int; } // Please note that I changed code, since this is the only way to get the type with which the template parameter was initialized U simp(T:MyAlias!U, U)(auto ref T val){ return U.init; } int main(){ simp(3); // val is inferred to be of type MyAlias!int simp(”4”); // val is of type MyAlias!string simp!string([4,0]); val is of type MyAlias!(int[]) MyAlias!float d =45; simp(d); // val is inferred to be of type MyAlias!(MyAlias!float) // hopefully though the second MyAlias doesn't have to exist and it can just assume the type to be int } ``` Edit: correcting the code ```d template MyAlias(T){ alias MyAlias = int; } // Please note that I changed code, since this is the only way to get the type with which the template parameter was initialized U simp(T:MyAlias!U, U)(auto ref T val){ return U.init; } int main(){ simp(3); // val is inferred to be of type MyAlias!int simp(”4”); // val is of type MyAlias!string simp([4,0]);// val is of type MyAlias!(int[]) MyAlias!float d =45; simp(d); // val is inferred to be of type MyAlias!(MyAlias!float) // hopefully though the second MyAlias doesn't have to exist and it can just assume the type to be int }
Re: Parameters declared as the alias of a template won't accept the arguments of the same type.
On Monday, 2 May 2022 at 22:01:51 UTC, ag0aep6g wrote: On 02.05.22 22:47, Stanislav Blinov wrote: On Monday, 2 May 2022 at 20:16:04 UTC, ag0aep6g wrote: On 02.05.22 21:17, Stanislav Blinov wrote: On Monday, 2 May 2022 at 16:29:05 UTC, Loara wrote: [...] ```d template MyAlias(T){ alias MyAlias = int; } T simp(T)(MyAlias!T val){ return T.init; } int main(){ simp(3);//Impossible to deduce T [...] That's not my answer. And it is nonsense, because my answer is - what T is irrelevant, MyAlias maps *all* types to int. Therefore `simp` takes an int, which is what the caller is passing. And what does it return? Perhaps one way could be to assume that the parameter passed is of type `aliasTemplate!typeOfVar` and see if it helps make sense of the invocation? This would only be done if the parameter's type doesn't directly match the required type nor it is implicitly convertible to it(which can be further constrained by... constraints...) For example, here: ```d template MyAlias(T){ alias MyAlias = int; } // Please note that I changed code, since this is the only way to get the type with which the template parameter was initialized U simp(T:MyAlias!U, U)(auto ref T val){ return U.init; } int main(){ simp(3); // val is inferred to be of type MyAlias!int simp(”4”); // val is of type MyAlias!string simp!string([4,0]); val is of type MyAlias!(int[]) MyAlias!float d =45; simp(d); // val is inferred to be of type MyAlias!(MyAlias!float) // hopefully though the second MyAlias doesn't have to exist and it can just assume the type to be int } ```
Re: Parameters declared as the alias of a template won't accept the arguments of the same type.
On Sunday, 1 May 2022 at 03:57:12 UTC, Elfstone wrote: module test; struct MatrixImpl(S, size_t M, size_t N) { } [...] AFAICT, I'm afraid you'll have to stick to `dot2` 🙁 This DIP I believe does what you want but... It wasn't looked upon favorably... https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1023.md
Re: error connecting to mongodb atlas with vibe.d
On Saturday, 30 April 2022 at 14:29:56 UTC, notsteve wrote: Hi, I am trying to setup a simple webserver in D using vibe.d (0.9.4) and want to use mongoDB as a database. To achieve this, I've set up a mongoDB atlas instance with the following command inside the standard app.d file created by vibe.d [...] Don't know if this will help or not, but someone wrote a book explaining vibed (and it's pretty recent too), maybe it'll contain some info regarding your issue https://github.com/reyvaleza/vibed/blob/main/BuildWebAppsinVibe.pdf Hope it helps!
Re: How to use destroy and free.
On Saturday, 30 April 2022 at 09:25:18 UTC, Dukc wrote: On Sunday, 24 April 2022 at 21:00:50 UTC, Alain De Vod wrote: [...] A few picks. 1: You do not need to import `destroy`. Everything in `object` is automatically imported. [...] Hell, just using `scope int[] i` should be enough to trigger deterministic destruction, no? `typecons`'s `Scoped!` template can be used if 100% guarantee is needed _and_ the memory has to be stack allocated
Re: T... args!
On Friday, 29 April 2022 at 16:10:52 UTC, Salih Dincer wrote: On Friday, 29 April 2022 at 12:57:15 UTC, Steven Schveighoffer wrote: [...] I see, think it can be done with mixin: ```d template prn(alias args) { string prn() { string result = "write("; foreach(s; args.split("|")) { result ~= format("%s,", s); } return result ~ ");"; } } void main() { int data = 456; char enter = '\n'; mixin(prn!q{ enter| 123 | " str " | data | enter|__TIME__ | enter } ); mixin( prn!q{"This value of " |41| " is prime."} ); } ``` If there was some convenience on the compiler side, we could integrate it into D. SDB@79 There's already an implementation of `mixin` string interpolation in https://github.com/Abscissa/scriptlike
Re: T... args!
On Friday, 29 April 2022 at 12:57:15 UTC, Steven Schveighoffer wrote: On 4/28/22 10:48 PM, Salih Dincer wrote: [...] There is no string interpolation in D. You can use a function such as `std.conv.text` to produce a string given interleaving strings and items. Or you can use `std.format.format` to make it happen. It looks like you want to take any number of parameters as a template parameter comprised of a tuple of strings? That isn't supported. What you instead created was a tuple with a name that shadows the outer name. Note that `string` is NOT a keyword in D, it's just an alias (one that the compiler recognizes specially). So it's possible to redefine string as a symbol to mean something else. -Steve It's not a keyword yet it's recognised specially by the compiler... What? I'm understanding the concept over here, but why didn't we make `string` a keyword anyways since the compiler recognises it specially?
Re: Is @live attribute working yet?
On Sunday, 24 April 2022 at 09:31:40 UTC, elfstone wrote: Dub(DMD 2.099.1) builds and runs the following code without a warning. import std.stdio; import core.stdc.stdlib; @live void test() { int* p = cast(int*) malloc(32); p = cast(int*) malloc(32); free(p); } void main() { test(); writeln("???"); } Isn't it supposed to trigger an error according to the doc (https://dlang.org/spec/ob.html)? @live void test() { auto p = allocate(); p = allocate(); // error: p was not disposed of release(p); } It's development is stalled 😞 https://forum.dlang.org/post/dvbqnlpqainnbtmbu...@forum.dlang.org
Re: A weird example of .toUTF16z concatination side-effects in wcsncat
On Thursday, 7 April 2022 at 10:50:35 UTC, BoQsc wrote: Here I try to concatenate three character strings using `wcsncat()`. [...] Maybe try using `wstring` instead of string? Also use the `w` postfix ```d wstring dlang_string = "BBB"w; I can't test because I'm not on my PC and I don't use Windows
Re: Mixin Templates and Operators
On Wednesday, 6 April 2022 at 10:36:04 UTC, francesco.andreetto wrote: I have two structs, point and vec, in which I want to implement some arithmetic operations. The operations are: ``` point - point = vec point + vec = point ``` Using mixin templates the code compiles but calling the operations in the main causes an "incompatible type" Error: ```d mixin template sum(T, R) { R opBinary(string op)(T rhs) const if (op == "+"){ return R(x + rhs.x, y + rhs.y, z + rhs.z); } } mixin template diff(T, R) { R opBinary(string op)(T rhs) const if (op == "-") { return R(x - rhs.x, y - rhs.y, z - rhs.z); } } struct point{ float x, y, z; mixin diff!(point, vec); mixin sum!(vec, point); } struct vec{ float x, y, z; } void main(){ point p1 = {1,2,3}, p2 = {5,6,7}; vec v1 = p1-p2; vec v2 = {2,-1,0}; point p3 = p1+v2; } ``` The output of `dub run` is ``` Performing "debug" build using /usr/bin/dmd for x86_64. query ~master: building configuration "application"... source/app.d(27,13): Error: incompatible types for `(p1) - (p2)`: both operands are of type `point` source/app.d(30,15): Error: incompatible types for `(p1) + (v2)`: `point` and `vec` /usr/bin/dmd failed with exit code 1. ``` I tried to implement a single template: ```d mixin template sumDiff(T, R){ R opBinary(string op)(T rhs) const if (op == "+" || op == "-"){ return mixin("R(x " ~ op ~ " rhs.x, y " ~ op ~ "rhs.y, z " ~ op ~ " rhs.z)"); } } ``` but the same error occurs. If I don't use the mixin templates and, instead, I overload the operations into the structures everything works. ```d struct point{ float x, y, z; vec opBinary(string op)(point rhs) const if (op == "-") { return vec(x - rhs.x, y - rhs.y, z - rhs.z); } point opBinary(string op)(vec rhs) const if (op == "+") { return point(x + rhs.x, y + rhs.y, z + rhs.z); } } struct vec{ float x, y, z; } void main(){ point p1 = {1,2,3}, p2 = {5,6,7}; vec v1 = p1-p2; vec v2 = {2,-1,0}; point p3 = p1+v2; } ``` Am I doing something wrong or it is impossible to use mixin templates like that? Looks like a compiler bug, since substituting the real methods makes the `mixin template` code compile fine Also, remove the `const`, otherwise the method will word only on `const` instances even if the bug gets fixed ```d mixin template sum(T, R) { R opBinary(string op)(T rhs) const if (op == "+"){ return R(x + rhs.x, y + rhs.y, z + rhs.z); } } mixin template diff(T, R) { R opBinary(string op)(T rhs) const if (op == "-") { return R(x - rhs.x, y - rhs.y, z - rhs.z); } } struct point{ float x, y, z; mixin diff!(point, vec); mixin sum!(vec, point); } struct vec{ float x, y, z; } void main(){ point p1 = {1,2,3}, p2 = {5,6,7}; vec v1 = p1.opBinary!"-"(p2); // made - explicit vec v2 = {2,-1,0}; point p3 = p1.opBinary!"+"(v2); // made + explicit }
Re: Where I download Digital Mars C Preprocessor sppn.exe?
On Sunday, 3 April 2022 at 08:37:45 UTC, user1234 wrote: On Saturday, 2 April 2022 at 21:57:02 UTC, Marcone wrote: Where I download Digital Mars C Preprocessor sppn.exe? I need it to use ImportC it's part of the [DMC] toolchain. [DMC]: http://ftp.digitalmars.com/Digital_Mars_C++/Patch/dm857c.zip Guys I think Ali is right... The post was meant as an April fool's joke... It was pretty badly mistimed though, at the time of his posting, it was 3rd April in my place, and undoubtedly 2nd everywhere else
Re: How to create delegates with an independent scope?
On Wednesday, 30 March 2022 at 12:46:07 UTC, Vijay Nayar wrote: Consider the following code example: ```d import std.stdio; void main() { alias DelegateT = string delegate(); // An array of delegates, each has their own scope. DelegateT[] funcs; foreach (i; ["ham", "cheese"]) { // Deliberately create a copy to keep in delegate scope. string myStr = i.dup; // The delegate will hopefully carry this copy around in its own scope. funcs ~= (() => myStr ~ " sandwich"); } foreach (f; funcs) { writeln(f()); } } ``` The expected output is: "ham sandwich" and then "cheese sandwich". The actual output is: "cheese sandwich" and then "cheese sandwich". It seems that the variable `myStr` is in a sort of shared scope for both functions in the array, and the last value written to it dominates. How do I create a delegate that acts like a [closure](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures), that is, it carries with it the environment in which it was created? You can also use `static foreach` and `alias`, although that will restrict that code to compile time usage only :/ ```d import std; import std.stdio; void main() { alias DelegateT = string delegate(); // An array of delegates, each has their own scope. DelegateT[] funcs; static foreach (alias i; ["ham", "cheese"]) { // Deliberately create a copy to keep in delegate scope. //string myStr = i.dup; // The delegate will hopefully carry this copy around in its own scope. funcs ~= (() => /*myStr*/ i ~ " sandwich"); } foreach (f; funcs) { writeln(f()); } } ```
Re: Tips on TCP socket to postgresql middleware
On Thursday, 24 February 2022 at 06:54:07 UTC, eugene wrote: On Thursday, 24 February 2022 at 06:30:51 UTC, Tejas wrote: On Wednesday, 23 February 2022 at 09:34:56 UTC, eugene wrote: On Tuesday, 22 February 2022 at 20:19:39 UTC, Chris Piker wrote: [...] As you might have been already noted, the key idea is to implement SM explicitly, i.e we have states, messages, actions, transitions and extremely simple engine (reactTo() method) [...] I remember you once mentioned a book that you used to learn this particular software design technique Could you please name it again? Thank you in advance Wagner F. et al Modeling Software with Finite State Machines: A Practical Approach I've adopted some ideas from this book to POSIX/Linux API. see also http://www.stateworks.com/ Thank you so much!
Re: Tips on TCP socket to postgresql middleware
On Wednesday, 23 February 2022 at 09:34:56 UTC, eugene wrote: On Tuesday, 22 February 2022 at 20:19:39 UTC, Chris Piker wrote: [...] As you might have been already noted, the key idea is to implement SM explicitly, i.e we have states, messages, actions, transitions and extremely simple engine (reactTo() method) [...] I remember you once mentioned a book that you used to learn this particular software design technique Could you please name it again? Thank you in advance
Re: ldc executable crashes with this code
On Wednesday, 2 February 2022 at 23:21:52 UTC, forkit wrote: Any reason why compiling this with ldc would cause the exe to crash? Compiling with DMD (using either declaration of palindrome works just fine though) // module test; import std; void main() { char[] palindrome = cast(char[])"able was I ere I saw elba"; //char[] palindrome = ['a','b','l','e','w','a','s','I','e','r','e','I','s','a','w','e','l','b','a']; writeln(palindrome); // note: The line below causes the exe to crash when compiled with ldc // but only if using the first version of palindrome. writeln(palindrome.reverse); } // --- This segfaults even on `dmd 2.098.0` for me. Clearly implementation defined behavior.
Re: number ranges
On Tuesday, 18 January 2022 at 20:43:08 UTC, forkit wrote: On Tuesday, 18 January 2022 at 16:02:42 UTC, Tejas wrote: Newer languages nowadays use `start..intent, think it's something we should follow? I've decided to avoid using number ranges 'directly', and instead use a wrapper function... auto range(T:T)(T a, T b) { import std.range : iota; return iota(a, (b+1)); } Aww, come on; it ain't that bad...
Re: number ranges
On Tuesday, 18 January 2022 at 17:58:54 UTC, H. S. Teoh wrote: On Tue, Jan 18, 2022 at 04:02:42PM +, Tejas via Digitalmars-d-learn wrote: [...] Newer languages nowadays use `start..intent, think it's something we should follow? I've never seen that before. Which languages use that? T In Nim for example: ``` for n in 5 .. 9: #Both 5 and 9 are included echo n echo "" for n in 5 ..< 9: #5 is included but 9 is excluded echo n ``` In Odin also: ``` for i in 0..<10 { fmt.println(i) } // or for i in 0..9 { fmt.println(i) } ```
Re: number ranges
On Monday, 17 January 2022 at 22:48:17 UTC, H. S. Teoh wrote: On Mon, Jan 17, 2022 at 10:35:30PM +, forkit via Digitalmars-d-learn wrote: On Monday, 17 January 2022 at 22:28:10 UTC, H. S. Teoh wrote: > [...] [...] If I were able to write a compiler, my compiler would warn you: "This is ill-advised and you should know better! Please rewrite this." :-D If *I* were to write a compiler, it'd come with a GC built-in. It'd throw up 90% of programs you feed it with the error "this program is garbage, please throw it away and write something better". :-D T Newer languages nowadays use `start..think it's something we should follow?
Re: non-constant expression ["foo":5, "bar":10, "baz":2000]
On Thursday, 6 January 2022 at 16:01:09 UTC, Stefan Koch wrote: On Thursday, 6 January 2022 at 12:04:12 UTC, HuskyNator wrote: On Monday, 28 November 2016 at 14:41:44 UTC, Era Scarecrow wrote: On Monday, 28 November 2016 at 09:06:34 UTC, Paolo Invernizzi wrote: The point is that I was trying to avoid some cycle between modules, detected by 2.072. This bug leads to pollution in the use of static this only to workaround the limitation... Wasn't someone working on a Associative Array static type that could be created at CTFE and run at runtime? I'm guessing there isn't. Sadly still running into issues because of this :( Actually I did a DMD patch for that some time ago. It's here: https://github.com/dlang/dmd/pull/13087 If there is interest in this I might revive it. I feel like this should be done, if only for the sake of consistency We can add an idiom about how initializing large AAs can lead to binary bloat, so use the `shared static this(){}` workaround instead Would you please revise it? I'll take your side on this.
Re: Libc functions undefined when linking
On Wednesday, 5 January 2022 at 16:14:02 UTC, Ben Jones wrote: On Wednesday, 5 January 2022 at 03:38:54 UTC, Tejas wrote: On Tuesday, 4 January 2022 at 18:13:56 UTC, Ben Jones wrote: The tricky part is that the lab machines that the students will be using don't have a D compiler installed (they're Fedora machines, and I didn't see a dmd package in their repos, or I would have asked the admins to install it). I'm using Fedora 34 `sudo dnf install ldc` works and gives ldc version 1.25.0(based on dmd 2.095.1)(but you invoke via `ldc2` or `ldmd2`) name of rpm: Source : ldc-1.25.1-2.fc34.src.rpm `sudo dnf install gcc-gdc` also works(but it's not the recent one with the D frontend)(you don't even need to write `gdc .d`, `gcc .d` also works.) name of rpm: Source : gcc-11.2.1-1.fc34.src.rpm good to know. What about dub? I can't say for sure, since I installed dmd from the website before installing the other two, but `dub` should be bundled with the other two as well Regardless, know that I didn't install dub seperately, it got installed with either the dmd rpm, or the LDC or GDC one
Re: Returning value by ref does not create a ref. Is this intentional?
On Wednesday, 5 January 2022 at 08:58:44 UTC, Dennis wrote: On Wednesday, 5 January 2022 at 05:38:45 UTC, Tejas wrote: The entire reason I wanted to get a `ref` was so that I can avoid the `*` :( I don't know what the real code behind the reduced example is, but maybe you can structure your code such that the subsequent modification `c = 10` happens in its own function. Then you can pass the result of `func(a)` to that function by `ref`. There isn't any complex code behind this. I was simply trying to emulate C++'s `int&`(or `T&` in general)
Re: Returning value by ref does not create a ref. Is this intentional?
On Wednesday, 5 January 2022 at 05:17:10 UTC, Stanislav Blinov wrote: It is returned. But initializing `c` with it makes a copy. Oh... Wish we had real `ref` ;( This will mutate `a`: ``` func(a) = 10; ``` Thank you for your help!
Re: Returning value by ref does not create a ref. Is this intentional?
On Wednesday, 5 January 2022 at 05:15:30 UTC, Paul Backus wrote: On Wednesday, 5 January 2022 at 04:35:12 UTC, Tejas wrote: ```d import std.stdio:writeln; ref int func(return ref int a){ a = 6; // modifies a as expected return a; } void main(){ int a = 5; auto c = func(a); // I expected c to alias a here c = 10; // Expected to modify a as well writeln(a); // prints 6 :( } ``` Local variables cannot be references, so when you assign the reference returned from `func` to the variable `auto c`, a copy is created. To make this work the way you want it to, you must use a pointer: ```d int a = 5; auto p = &func(a); // use & to get a pointer *p = 10; writeln(a); // prints 10 ``` The entire reason I wanted to get a `ref` was so that I can avoid the `*` :( Didn't know you could take the address of a function _invocation_ though, so asking this wasn't completely redundant Thank you :D Guess I'll be stuck with ol' `struct Ref(T){...}`
Returning value by ref does not create a ref. Is this intentional?
```d import std.stdio:writeln; ref int func(return ref int a){ a = 6; // modifies a as expected return a; } void main(){ int a = 5; auto c = func(a); // I expected c to alias a here c = 10; // Expected to modify a as well writeln(a); // prints 6 :( } ``` The [spec](https://dlang.org/spec/function.html#ref-functions) states: Ref functions allow functions to return by reference, meaning that the return value must be an lvalue, and the lvalue is returned, not the rvalue. Then why does the reference to `a` not get returned ?
Re: Libc functions undefined when linking
On Tuesday, 4 January 2022 at 18:13:56 UTC, Ben Jones wrote: The tricky part is that the lab machines that the students will be using don't have a D compiler installed (they're Fedora machines, and I didn't see a dmd package in their repos, or I would have asked the admins to install it). I'm using Fedora 34 `sudo dnf install ldc` works and gives ldc version 1.25.0(based on dmd 2.095.1)(but you invoke via `ldc2` or `ldmd2`) name of rpm: Source : ldc-1.25.1-2.fc34.src.rpm `sudo dnf install gcc-gdc` also works(but it's not the recent one with the D frontend)(you don't even need to write `gdc .d`, `gcc .d` also works.) name of rpm: Source : gcc-11.2.1-1.fc34.src.rpm
Re: function(pointer) as template argument, explicit template instantiation
On Friday, 31 December 2021 at 00:57:26 UTC, kdevel wrote: ```dptr.d class R { } void foo (R r) { } alias fn = void function (R); void lyr (fn F) (R r) { } immutable fn foo_ptr = &foo; // line 14 pragma (msg, typeof (foo_ptr)); auto ptr = lyr!(foo_ptr);// line 17 ``` dmd reports: ``` immutable(void function(R)) dptr.d(14): Error: expression `& foo` is not a valid template value argument ``` If I comment out line 17 the code compiles. I want to put the explicitly instantiated function template into an immutable AA. How can that be phrased such that dmd compiles it? Is it okay to use template parameter instead of **template value** parameter? ```d class R { } void foo (R r) { } void lyr (fp_type, R) (fp_type fp, R r) { } pragma (msg, typeof (&foo)); R r; void main(){ auto foo_ptr = &foo; lyr(foo_ptr, r); } ```
Re: print ubyte[] as (ascii) string
On Thursday, 30 December 2021 at 17:31:27 UTC, eugene wrote: On Thursday, 30 December 2021 at 16:49:17 UTC, Tejas wrote: I _think_ the above code is correct, please verify Self-contained example: ```d import std.stdio; import std.string; void main() { ubyte[8] b = [0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00]; /* "hello\n\0\0" */ char[] s = fromStringz(cast(char*)b.ptr); writefln("'%s, world'", s.strip); s = cast(char[])b[0 .. $]; writefln("'%s, world'", s.strip); } ``` Output: ``` @mono:~/2-coding/d-lang/misc$ ./p 'hello, world' 'hello , world' ``` I'm not at my computer anymore, could you please replace the `0x00` with `0x0A` and tell me if `strip` still doesn't work for my solution? I think the `fromstringz` is trimming the null bytes for you, making the `\n` the last character, allowing `strip` to work.
Re: print ubyte[] as (ascii) string
On Thursday, 30 December 2021 at 17:07:20 UTC, eugene wrote: On Thursday, 30 December 2021 at 16:49:17 UTC, Tejas wrote: ```d char[] s = cast(char[])ioCtx.buf[0 .. $];// please remember that in `[0 .. $]` last index is automatically `length - 1` but just buf[$] will be an error since there the actual `length` will be used ``` I _think_ the above code is correct, please verify There is one pecularity: ```d char[] s = fromStringz(cast(char*)ioCtx.buf.ptr); writefln("got '%s' from '%s:%d'", s.strip, client.addr, client.port); // strip works :) ``` ```d char[] s = cast(char[])ioCtx.buf[0 .. $]; writefln("got '%s' from '%s:%d'", s.strip, client.addr, client.port); // strip does not work :( ``` I'll need to know the error message, because the following works: ```d import std; void main() { ubyte[] c ; c.length = 100; char[] arr = cast(char[])c[0 .. $]; foreach(ref elem; arr) elem = 'a'; writeln(arr.strip); } ```
Re: print ubyte[] as (ascii) string
On Thursday, 30 December 2021 at 09:34:27 UTC, eugene wrote: I suspect the question was asked somewhere before. If so just give a link. Anyway: ```d class IoContext { ... ubyte[] buf; ... this(uint bufSize) { buf = new ubyte[bufSize]; } } ``` ```d class IoContext { ... ubyte[] buf; ... this(uint bufSize) { buf.length = bufSize; //this should do the same thing, I believe } } ``` The buffer contains (ascii) string terminated with '\n'. In order to print it not as an array of numbers (buf is 1024 bytes long), but as usual string I do ```d char[] s = cast(char[])ioCtx.buf[0 .. strlen(cast(char*)ioCtx.buf.ptr) - 1]; // -1 is to eliminate terminating '\n' writefln("got '%s' from '%s:%d'", s, client.addr, client.port); ``` ```d char[] s = cast(char[])ioCtx.buf[0 .. $];// please remember that in `[0 .. $]` last index is automatically `length - 1` but just buf[$] will be an error since there the actual `length` will be used ``` I _think_ the above code is correct, please verify
Re: How are extra copy constructor parameters used?
On Thursday, 30 December 2021 at 04:42:06 UTC, Tejas wrote: On Thursday, 30 December 2021 at 01:04:10 UTC, Ali Çehreli wrote: The second item in the documentation mentions "any number of default parameters" when describing copy constructor syntax: https://dlang.org/spec/struct.html#struct-copy-constructor 1) I can't figure out how to use those extra parameters. For example, I can't find a special function name to call explicitly: S.__cctor(a, 42); // No go Behold the pathetic hack! ```d import std.stdio:writeln; struct A { this(ref return scope A rhs) inout {} // copy constructor this(ref A rhs, int b = 7) inout { // copy constructor with default parameter if (b != 7) { rhs.b = b;//yes, modify the parameter, not the this object :( rhs.a = rhs.a; } else foreach (i, ref field; rhs.tupleof) field = this.tupleof[i] ; } this(this) @disable; int a=4; int b=3; } void main() { A a = A(); A b = void; a.__ctor(b, 9); // because writing A b = A(a, 9); like a sane human is giving errors D: writeln(b.b); } ``` Replacing `a.__ctor(b, 9);` with `A b = A(a, 9);` is yielding: ```d onlineapp.d(26): Error: cannot implicitly convert expression `a` of type `A` to `int` ``` Ehh no need to get overly dramatic, I could've done `b.__ctor(a,9)` in order to prevent mutation via the parameter ```d import std.stdio:writeln; struct A { this(ref return scope A rhs) inout {} // copy constructor this(ref return scope const A rhs, int b = 7) inout { // copy constructor with default parameter if (b != 7) { this.b = b; this.a = rhs.a; } else foreach (i, ref inout field; rhs.tupleof) this.tupleof[i] = field; } this(this) @disable; int a=4; int b=3; } void main() { A a = A(); A b = void; b.__ctor(a, 9); //b = A(a,9); //this still doesn't work :( writeln(b.b); writeln(b); } ```
Re: How are extra copy constructor parameters used?
On Thursday, 30 December 2021 at 01:04:10 UTC, Ali Çehreli wrote: The second item in the documentation mentions "any number of default parameters" when describing copy constructor syntax: https://dlang.org/spec/struct.html#struct-copy-constructor 1) I can't figure out how to use those extra parameters. For example, I can't find a special function name to call explicitly: S.__cctor(a, 42); // No go Behold the pathetic hack! ```d import std.stdio:writeln; struct A { this(ref return scope A rhs) inout {} // copy constructor this(ref A rhs, int b = 7) inout { // copy constructor with default parameter if (b != 7) { rhs.b = b;//yes, modify the parameter, not the this object :( rhs.a = rhs.a; } else foreach (i, ref field; rhs.tupleof) field = this.tupleof[i] ; } this(this) @disable; int a=4; int b=3; } void main() { A a = A(); A b = void; a.__ctor(b, 9); // because writing A b = A(a, 9); like a sane human is giving errors D: writeln(b.b); } ``` Replacing `a.__ctor(b, 9);` with `A b = A(a, 9);` is yielding: ```d onlineapp.d(26): Error: cannot implicitly convert expression `a` of type `A` to `int` ```
Re: opCast + dtor error
On Tuesday, 28 December 2021 at 18:27:36 UTC, vit wrote: Hi, why this code doesn't compile? ```d struct Foo{ bool opCast(T : bool)()const{ assert(0); } ~this(){} } struct Bar{ const Foo foo; } void main(){ } ``` Error: template instance `opCast!(Foo)` does not match template declaration `opCast(T : bool)()` Since a destructor ignores `const`, I think adding the `~this` to Foo manually is somehow making the compiler have to actually cast away const, which it is doing via `cast(Foo) foo`, which fails since you've declared your own `opCast` that only accepts arguments implicitly convertible to `bool`. I say this because removing the specialisation in `opCast` and changing the return type of it to `Foo` works : ```d struct Foo{ Foo opCast(T)()const { assert(0); return this; } ~this() {} } struct Bar{ const Foo foo; } void main(){ //Bar bar = Bar(); //this will trigger the assertion failure } ```
Re: Starting and managing threads
On Tuesday, 28 December 2021 at 16:29:05 UTC, Bagomot wrote: I can't do it according to your example, my Watcher list fills up at runtime. Yes, it's possible to do it at runtime as well(it already _was_ happening at runtime), although I'll be using a `cast` for convenience now. ```d import std.concurrency; import core.thread; import std.stdio:writeln,readf; void main() { writeln("Please enter num of elements"); int a; readf!"%d"(a); foreach(number; 0..a){ Test.getInstance.watchers ~= new Watcher();//will have to use operations from core.atomic if you want to read/write shared variables, that's why I didn't declare the array as shared } Test.getInstance.run; } class Test { private { __gshared Test instance; /+shared+/ Watcher[] watchers; } protected this() { } public static Test getInstance() { if (!instance) { synchronized (Test.classinfo) { if (!instance) instance = new Test; } } return instance; } public void run() { foreach (ref watcher; cast(shared)/+using cast so that TLS gets disabled)+/this.watchers) { spawn(&Watcher.run, watcher); } } } class Watcher { static public void run(shared Watcher watcher) { while (true) { // job writeln("It works now :D"); break; } } } ```
Re: Starting and managing threads
On Tuesday, 28 December 2021 at 14:19:46 UTC, Bagomot wrote: On Monday, 27 December 2021 at 10:59:07 UTC, Ali Çehreli wrote: On 12/27/21 1:33 AM, Bagomot wrote: > separate thread, without blocking the main one. I think you can use std.concurrency there. I have a chapter here: http://ddili.org/ders/d.en/concurrency.html Look for 'struct Exit' to see how the main thread signals workers to stop running. And some std.concurrency hints appear in my DConf Online 2020 presentation here: https://dconf.org/2020/online/#ali1 Ali I tried to run with std.concurrency via spawn, but this does not work for me for the reason that in the program I run the thread not from main, but from the object. It looks something like this: ```d import std.concurrency; import std.thread; void main() { Test.getInstance.run; } class Test { private { __gshared Test instance; Watcher[] watchers; } protected this() { } public static Test getInstance() { if (!instance) { synchronized (Test.classinfo) { if (!instance) instance = new Test; } } return instance; } public void run() { foreach (Watcher watcher; this.watchers) { spawn(&watcher.run); } } } class Watcher { public void run() { while (true) { // job } } } ``` Error: template `std.concurrency.spawn` cannot deduce function from argument types `!()(void delegate())`. I would not want to do this from main because it breaks the structure of my program. Is there a way to do it the way I want? Yes, you'll have to make the function that you want to run static and all the arguments must be `shared` qualified, ie, TLS not allowed ```d import std.concurrency; import core.thread; import std.stdio:writeln; void main() { Test.getInstance.run; } class Test { private { __gshared Test instance; shared Watcher[] watchers = [new Watcher(), new Watcher()]; //notice the shared // I used 2 values just to show some output } protected this() { } public static Test getInstance() { if (!instance) { synchronized (Test.classinfo) { if (!instance) instance = new Test; } } return instance; } public void run() { foreach (ref/+use ref to ensure no copies are made. I don't tknow the right thing to do here, the errors went away when I used ref so...+/ watcher; this.watchers) { spawn(&Watcher.run, watcher); } } } class Watcher { static public void run(shared Watcher watcher/+sending as argument since function can't have an invisible this parameter anymore+/) {//now this is static while (true) { // job writeln("It works now :D"); break; //wrote this so that you can copy-paste to run.dlang.io } } } ```
Re: AA and struct with const member
On Tuesday, 28 December 2021 at 01:45:42 UTC, Era Scarecrow wrote: On Monday, 27 December 2021 at 19:38:38 UTC, frame wrote: [...] const/immutable members are to be set/assigned instantiation. Most likely the problem is a bug and sounds like [...] The workaround is okay, but I think we should file a bug report for this. This is very ~~stupid~~ undesirable behaviour
Re: Good intellisense support IDE/Editor?
On Wednesday, 22 December 2021 at 11:50:06 UTC, evilrat wrote: On Wednesday, 22 December 2021 at 10:37:51 UTC, Michel wrote: Hey, I've tried coding in Visual Studio Code but there isn't any function checking/showing what arguments a function accepts, I can just write `Foo.Bar("somerandomarg");` and it will not give me errors or warnings. Which IDE do you guys use to get proper intellisense? Thanks VS Code(code-d plugin) and VisualD(Visual Studio only) are the best available for D and does show you errors like that if set up and cofigured correctly, but really nowhere near compared to pro tools for C#/Java, additionally most D language plugin/IDE relies on "dcd" or "libdparse", which becoming less and less useful as D evolves. (I don't blame them, but unfortunately their time has passed) Finally there is no tool that can handle complex UFCS chains or templates(like filter, map, etc..). Stefan said on his Q&A video of Dconf 2021 that the compiler-as-a-daemon will be available after he has successfully completed task-ification of dmd. Maybe we still have hope :D
Re: Small structs: interfacing with C++ potentially broken
On Monday, 20 December 2021 at 11:58:03 UTC, Tim wrote: On Monday, 20 December 2021 at 10:24:00 UTC, Jan wrote: Is this a known issue, or is there a way to instruct DMD to use a specific calling convention for a given type? This looks like a bug. It seems to work without constructor in C++, but still crashes with a constructor in D. It also seems to work if a trivial destructor is added in D: ~this(){} This could be related to POD types in C++. Structs with constructor or destructor are probably passed differently, but dmd only looks at the destructor. I think it's got something to do with [this](https://forum.dlang.org/post/capevemlbdanirtcj...@forum.dlang.org)
Re: How to insert code in place with templates/mixins?
On Monday, 20 December 2021 at 11:30:09 UTC, rumbu wrote: On Monday, 20 December 2021 at 10:49:20 UTC, rempas wrote: On Monday, 20 December 2021 at 09:30:30 UTC, rumbu wrote: Thanks a lot for the info. When I try to use this code, I'm getting the following error: ``` Error: expression expected, not `%` Error: expression expected, not `%` ``` My fault, I forgot to put some char delimiters. You can find tested code here: https://run.dlang.io/is/KfdED0 So I suppose there is a problem with string concatenation. I couldn't use it anyway because it is inefficient and because I'm using betterC. Do you know any other way that I can concatenate strings that does not depend an the Garbage Collector or the standard library? Enums (that's why the string is declarated as enum) are evaluated at compile time, the concatenation op will not end in your code as instruction, so you can do anything outside betterC rules as long you do it at compile time. You are just building some code to use later, the compiler does not generate any instruction for it. In the example above you can press the AST button to see exactly how your code is generated. Wnen you have doubts about a generated string you can always test it with ```pragma msg```. In this case, if you write: ``` pragma(msg, add_char!'%'); ``` you will have in the output exactly what the compiler will generate for your mixin. Ehh, it still fails; should've explicitly put the length of the array and the `extern (C)` in `main` ```d module demo; //i am just declaring these to have them. size_t stdout_index; enum STDOUT_BUF_LEN = 42; char[STDOUT_BUF_LEN] stdout_buffer; /+indexing an uninitialized dynamic array resulted in out of bounds error even for index == 0+/ alias i32 = int; void sys_write(int i, void* p, int index) {} // enum add_char(char c) = `if (stdout_index < STDOUT_BUF_LEN) { stdout_buffer[stdout_index++] ='` ~ c ~ `'; continue; } else { sys_write(1, stdout_buffer.ptr, cast(i32)stdout_index); stdout_index = 0; stdout_buffer[stdout_index++] ='` ~ c ~ `'; continue; }`; extern(C) /+added this because you used -betterC+/ void main() { while (true) { mixin(add_char!'%'); mixin(add_char!'$'); } } ```
Re: dynamic array + copy ctor
On Sunday, 19 December 2021 at 22:29:21 UTC, vit wrote: Hello, Why is copy ctor in this example not called? ```d import std.stdio; struct Foo { int i; this(int i){ this.i = i; writeln("init: ", i); } this(ref typeof(this) rhs){ this.i = rhs.i; writeln("copy: ", i); } ~this() { writeln("~dtor:", i); } } void main(){ Foo[] foos; foos ~= Foo(1); while(foos.capacity > foos.length) foos ~= Foo(0); foos ~= Foo(2); import core.memory; GC.collect(); } ``` result: ``` init: 1 init: 2 ~dtor:1 ~dtor:2 ~dtor:1 ``` First Foo is destructed 2x. Yeah, Stanislov is right, it's using a blit rather than a copy constructor: ```d import std.stdio; struct Foo { int i; this(this){ writeln("blit: ", i); } this(int i){ this.i = i; writeln("init: ", i); } this(scope ref Foo rhs){ this.i = rhs.i; writeln("copy: ", i); } ~this() { writeln("~dtor:", i); writeln("~dtor:", &this); } } void main() { Foo[] foos ; foos ~= Foo(1); foos ~= Foo(2); } /+ Output: init: 1 init: 2 blit: 1 ~dtor:1 ~dtor:7EFE0DCD3000 ~dtor:2 ~dtor:7EFE0DCD4004 ~dtor:1 ~dtor:7EFE0DCD4000 +/ ```
Re: ImportC: Should this compile?
On Sunday, 19 December 2021 at 02:57:35 UTC, Mike Parker wrote: On Saturday, 18 December 2021 at 22:31:38 UTC, bachmeier wrote: I've been trying to get the stb header library to compile. There's a single remaining failure: ``` typedef struct { unsigned char c[4]; } stb_easy_font_color; stb_easy_font_color c = { 255,255,255,255 }; // use structure copying to avoid needing depending on memcpy() ``` LDC returns ``` stb_easy_font.c(892): Error: 3 extra initializer(s) for `struct __tag21` ``` Is this a bug in ImportC or is it correct that it doesn't compile? What's the best way to fix it while keeping the same behavior and performance? Unless C11 has changed the rules about nested initializers, that should compile. You might try explicit nesting: ```d stb_easy_font_color c = { {255,255,255,255} }; ``` And please file an issue if there isn't one already. (I don't know what struct __tag21 is. It's not anywhere in the source. Assuming that's just a bad error message.) A "tag" is the name of a struct or union, which follows the keyword: ```c struct Foo {}; ``` Here, `Foo` is the tag. Instances of the struct must be declared as `struct Foo`. Think of it like this: `int` is required in declarations of instances of type `int`, so `struct` is required in declarations of type `struct`; the "tag" specifies which struct type, hence `struct Foo x`. `typedef` introduces an alias: ```c typedef struct Bar {} Bar; ``` So `Bar` is now an alias for `struct Bar`, and instances can be declared as `Bar x`. Your example is like this: ```c typedef struct {} stb_easy_font_color; ``` No tag is specified, so the compiler must generate one. In your case, it's `__tag21` and `stb_easy_font_color` is an alias for `struct __tag21`. And yes, using the generated tag in the error message is not at all helpful without the alias. Please file an issue on this, too. Yes, using the nested initializer worked ```c typedef struct { unsigned char c[4]; } stb_easy_font_color; stb_easy_font_color c = { { 255,255,255,255 } }; // use structure copying to avoid needing depending on memcpy() ``` d file: ```d void main(){} ``` command line: ` dmd stuff.c main.d` Oh wow, the executable gets named `stuff` if that's the first file passed... always thought it would name it the same name as that file which contained `main`
Re: This is bug or not? (immutable class containing struct with dtor)
On Saturday, 18 December 2021 at 11:01:53 UTC, Denis Feklushkin wrote: On Friday, 17 December 2021 at 19:03:05 UTC, Tejas wrote: Well, I got completely mislead by my experiment 😓 ```d struct S { ~this() immutable {} } ``` Interesting what discussed behaviour isn't affects method what implements same functionality as dtor and called explictly at each appropriate place. So for dirty fix I just created ```d void __custom_dtor() const { ... } ``` And then called this __custom_dtor at each dtor what uses this struct. As Ali said, this is an implementation issue. So I guess the answer to your question is that this is a bug. Please file a report at [issues.dlang.org](issues.dlang.org)
Re: This is bug or not? (immutable class containing struct with dtor)
On Friday, 17 December 2021 at 18:51:56 UTC, Ali Çehreli wrote: On 12/17/21 10:01 AM, Tejas wrote: > [...] Storage, There is no such requirement nor guarantee. [...] Well, I got completely mislead by my experiment 😓 ```d struct S { ~this() immutable {} } void main() { immutable S s = S(); } ``` This failed, so I just came up with reasons to justify this behaviour Thanks for correcting me 😃
Re: This is bug or not? (immutable class containing struct with dtor)
On Friday, 17 December 2021 at 18:32:43 UTC, Denis Feklushkin wrote: On Friday, 17 December 2021 at 18:02:52 UTC, Tejas wrote: I improved your sample: ```d immutable struct S { ~this() {} } immutable struct S2 { S sss; ~this() {} } void main() { S2 s = S2(); } ``` ``` Error: `immutable` method `serializer_bug.S.~this` is not callable using a mutable object Error: mutable method `serializer_bug.S2.~this` is not callable using a `immutable` object serializer_bug.d(17,5):Consider adding `const` or `inout` here ``` immutable dtor can't be called at all? Nope, seems to go against the very promise it's making Labelling `~this()` as const or immutable means it won't affect the state of the object, but it will, by it's very nature. That's why I said it's not too much of a stretch to imagine why they're disallowed entirely.
Re: This is bug or not? (immutable class containing struct with dtor)
On Friday, 17 December 2021 at 18:19:34 UTC, Denis Feklushkin wrote: On Friday, 17 December 2021 at 18:01:03 UTC, Tejas wrote: I think since `immutable` objects are kept in Read Only Storage Some of them can be stored in ROM in some cases, but actually "immutable" keyword means "not mutable for whole its lifetime" Well, it would be really weird if destructors successfully executed for some class of `immutable` qualified objects but didn't for others. Not too much of a stretch to imagine that destruction for immutable objects was outright disallowed. Someone who can explain this behaviour more thoroughly would be much appreciated 😊 Maybe we should allow finalizers to mutate their instance?
Re: This is bug or not? (immutable class containing struct with dtor)
On Friday, 17 December 2021 at 18:01:03 UTC, Tejas wrote: On Friday, 17 December 2021 at 17:34:05 UTC, Denis Feklushkin wrote: On Friday, 17 December 2021 at 17:27:53 UTC, Denis Feklushkin wrote: [...] ("serializer_bug" is just name of my local .d file) I think since `immutable` objects are kept in Read Only Storage, you can't call destructors on them since the objects don't get erased when `~this` is called, but rather they get assigned their `.init` value, which tells the GC that they can be collected. `immutable class` has nothing to do with it, even the following fails to compile: ```d struct S { ~this() immutable {} } void main() { S s = S(); } Error: `immutable` method `onlineapp.S.~this` is not callable using a mutable object ``` Correction: `immutable S s = S();` inside the `void main()`
Re: This is bug or not? (immutable class containing struct with dtor)
On Friday, 17 December 2021 at 17:34:05 UTC, Denis Feklushkin wrote: On Friday, 17 December 2021 at 17:27:53 UTC, Denis Feklushkin wrote: ~this() {} // Comment out this to fix this compilation error: // Error: `immutable` method `serializer_bug.Imm.~this` is ("serializer_bug" is just name of my local .d file) I think since `immutable` objects are kept in Read Only Storage, you can't call destructors on them since the objects don't get erased when `~this` is called, but rather they get assigned their `.init` value, which tells the GC that they can be collected. `immutable class` has nothing to do with it, even the following fails to compile: ```d struct S { ~this() immutable {} } void main() { S s = S(); } Error: `immutable` method `onlineapp.S.~this` is not callable using a mutable object ```
Re: Why code failed to compile for foo2?
On Tuesday, 14 December 2021 at 15:14:40 UTC, Steven Schveighoffer wrote: On 12/14/21 12:04 AM, Tejas wrote: Is there anything wrong with the answer I posted? Can you please tell me if there's anything dissatisfactory about it? I feel like it does everything the OP wants. Also, am I wrong in using `Unconst` over `Unqual`? Isn't `Unqual` overkill if you just want to cast away `const`? Unqual is fine for value types, it should work in all cases. The OP's problem is that it's entirely possible to build an overload set with *just* the unqualified types specified (in this case, an integral type), but there's not a way to express that and still have it work with IFTI. In other words, if you have a call like: ```d const int x; foo2(x); ``` You want to have the parameter be mutable inside foo2. There currently isn't a way to express that if `foo2` is an IFTI template. The opposite is actually easily expressable: ```d void foo2(T)(const(T) val) { // only one instantiation of foo2 per const(int), immutable(int), int, // and now val is const, even if the argument is not } ``` With a standard function it works just fine due to implicit conversion, but with IFTI, there's no way to express it because it goes through an alias. The closest you can come is to write a wrapper shim that calls the right instantiation. This should be OK as long as inlining is happening, but it seems like extra work for the optimizer, when it should be easy to express in the language somehow. BTW, there is a related issue: https://issues.dlang.org/show_bug.cgi?id=1807 -Steve Yeah, now I understand he's trying to reduce number of instantiations. In that case, I'd use `inout`, but it'd be the same as your case : can't modify the argument anymore. But we can pass that to another function that accepts `ulong` (as that seems to be the OP's usecase anyways), which can then modify it :D ```d import std.traits : Unconst; import std.stdio : writeln; void foo2(T)(inout(T) x) if(is(Unconst!(T) : ulong)) {//You don't need Unqual for this pragma(msg, T.stringof); foo3(x); } void foo3(ulong param){ writeln(param, " before"); param +=10; writeln(param, " after"); // can also modify params now } void main(){ import std.math; const int ci = -3; int i = -2; immutable int ii = 24342; foo2(abs(ci)); foo2(abs(i)); foo2(ii); byte b = 0; const byte cb; immutable byte ib; foo2(b); foo2(cb); foo2(ib); const long cl = 4554; long l = 12313; immutable long il = 3242343; foo2(cl); foo2(l); foo2(il); } ```
Re: Why code failed to compile for foo2?
On Tuesday, 14 December 2021 at 13:25:04 UTC, apz28 wrote: On Tuesday, 14 December 2021 at 05:04:46 UTC, Tejas wrote: Is there anything wrong with the answer I posted? Can you please tell me if there's anything dissatisfactory about it? I feel like it does everything the OP wants. Also, am I wrong in using `Unconst` over `Unqual`? Isn't `Unqual` overkill if you just want to cast away `const`? 1. A template function should behave as to replace 4 overload functions There is special logic for parameter type (2 vs 4...) 2. Your implementation does not remove 'const' as below import std.traits : Unconst; import std.stdio : writeln; void foo2(T)(T x) if(is(Unconst!(T) : ulong)) {//You don't need Unqual for this pragma(msg, T.stringof); writeln(x); } void main() { import std.math; const int s1 = -3; int s2 = -2; foo2(abs(s1)); foo2(abs(s2)); enum byte b1 = 0; const byte b2; byte b3; foo2(b1); foo2(b2); foo2(b3); } --Output const(int) int byte const(byte) 3 2 0 0 0 Then I suggest using `inout`, if you're trying to reduce number of template instantiations ```d import std.traits : Unconst; import std.stdio : writeln; void foo2(T)(inout(T) x) if(is(Unconst!(T) : ulong)) {//You don't need Unqual for this pragma(msg, T.stringof); writeln(x); } void main(){ import std.math; const int ci = -3; int i = -2; immutable int ii = 24342; foo2(abs(ci)); foo2(abs(i)); foo2(ii); byte b = 0; const byte cb; immutable byte ib; foo2(b); foo2(cb); foo2(ib); const long cl = 4554; long l = 12313; immutable long il = 3242343; foo2(cl); foo2(l); foo2(il); } Output(Compile-time): int byte long Output(Runtime): 3 2 24342 0 0 0 4554 12313 3242343 ```
Re: template ctor overload Segmentation fault
On Tuesday, 14 December 2021 at 12:04:36 UTC, RazvanN wrote: On Sunday, 12 December 2021 at 11:57:43 UTC, vit wrote: [...] The problem is that the compiler will try to generate an inout copy constructor for Bar that looks roughly like this: ``` this(ref scope inout(Bar) p) inout { this.foo = p; } ``` The idea behind this lowering is to try and call the copy constructor for Foo object if possible. One issue here is that copy constructors have the same symbol name as constructors (__ctor), so `this.foo = p` gets lowered to `foo.__ctor(p)`. Since both the instance and the parameter are inout, the copy constructor of Foo cannot be called, so the templated constructor is called. After generating the template instance of the constructor, you end up with `this(scope inout(Foo)) inout` ; that is basically an rvalue constructor. This is not valid code; if you write: ``` struct Foo(T){ //this(Rhs, this This)(scope Rhs rhs){} this(scope inout(Foo!int) rhs) inout {} this(ref scope typeof(this) rhs){ } } ``` You will get an error stating that you cannot define both an rvalue constructor and a copy constructor. However, since the constructor is templated it is impossible for the compiler to issue this error before actually instantiating the constructor. I see 2 possible fixes for this: (1) either we rename the copy constructor symbol to __cpCtor so that it does not clash with the normal constructor overload set or (2) when a templated constructor is instantiated, we can check whether it is an rvalue constructor and issue an error if a copy constructor exists. When I implemented the copy constructor I thought that it would better to have the copy constructor on a different overload set than the normal constructors, however, Walter insisted that they have the same name. So, I guess (2) is the way to go. Cheers, RazvanN Then why did my modification work? ```d struct Foo(T){ this(Rhs, this This)(scope Rhs rhs){ } this(scope Foo!(T)* rhs){ //replaced typeof(this) with Foo!T and ref with pointer. Code still works if I retain typeof(this) } } struct Bar{ Foo!int foo; } void main(){ import std.stdio:writeln; Bar bar = Bar(); auto BAR = new Bar(); writeln(bar, "\t", BAR, "\t", *BAR); } ``` Did my modifications ensure that this is not treated as a copy constructor?
Re: How to pass a class by (const) reference to C++
On Monday, 13 December 2021 at 12:08:30 UTC, evilrat wrote: On Monday, 13 December 2021 at 11:13:12 UTC, Tejas wrote: On Monday, 13 December 2021 at 09:21:26 UTC, Jan wrote: [...] You'll have to use something called a [shim](https://en.wikipedia.org/wiki/Shim_(computing)), it seems. For example: `main.d` : ```d extern(C++) class A{} extern(C++) void cppFunc_shim(A arg); void main(){ A a = new A(); cppFunc_shim(a); } ``` `cppShim.cpp` : ```c++ class A{}; extern void cppFunc(A const &arg); void cppFunc_shim(A *param){ const A forwardingVar = A(*param); cppFunc(forwardingVar); } ``` `cppFunc.cpp` : ```c++ #include "iostream" class A{}; void cppFunc(A const &arg){ //std::cout << arg << std::endl; std::cout << "Called cppFunc :D" << std::endl; } ``` Then pass the following on the command line(assuming all files are in the same directory): `ldmd2 main.d cppFunc.o cppShim.o -L-lstdc++` That's what it took to make it work for me, dunno if more convenient methods exist. Hope it helps :D Yeah but it sucks to have making C++ wrapper just for this. I think either pragma mangle to hammer it in place or helper dummy struct with class layout that mimics this shim logic is a better solution in such cases. Literally anything but building C++ code twice for a project. Hey, evilrat, I've seen people make claims that our C++ interop has reached phenomenal levels and that going any further would basically require a C++ compiler ala ImportC++, the issue is just that the docs haven't been updated yet to reflect it. What do you think about this? Is this really true? Because it sure doesn't look that way to me :(
Re: Passing a derived class where base class is defined as ref parameter
On Monday, 13 December 2021 at 22:30:59 UTC, Adam D Ruppe wrote: On Monday, 13 December 2021 at 22:06:45 UTC, chopchop wrote: If I remove the ref, it works as expected, that is to say I can give a derived class as parameter. Why are you using the ref to begin with? What the logic here? Consider this: class C : A {} void incr(ref A a) { a = new C; } B b = new B; incr(b); // oops b now got rebound to a C instead of to a B, which breaks everything But `B` is not a child of `A`, why should it be accepted in a function that accepts `A` as a parameter? It's not implicitly convertible to `A`
Re: Why code failed to compile for foo2?
On Monday, 13 December 2021 at 20:43:51 UTC, Steven Schveighoffer wrote: On 12/11/21 10:02 PM, apz28 wrote: On Sunday, 12 December 2021 at 00:02:25 UTC, Stanislav Blinov wrote: @apz28, I can't figure out the intent here. To convert result of abs to an unsigned? The function logic works only for unsigned type and the parameter value can be altered in body hence Unqual. If not Unqual, must declare a local var and make a copy. Just asking if this can be done to avoid a cast by caller To translate a bit here, what apz28 is looking for is, given ANY value type that implicitly converts from the qualified value to the unqualified value, generate *one* function that only accepts the unqualified value. You can wrap like: ```d void foo2(T)(T v) if (!is(Unqual!T == T)) { foo(Unqual!T(t)); } ``` This will inline as if you called it directly (which should just whittle down to a direct call to the correct foo2). But D isn't currently smart enough to see through aliases, so IFTI will not work for what you are doing, even in a case like: ```d template foo2(T) if (!isUnqual!T == T) { alias foo2 = .foo2!(Unqual!T); } ``` It would be nice if IFTI gave some hooks between the parameter and the deduction, but it currently doesn't. -Steve Is there anything wrong with the answer I posted? Can you please tell me if there's anything dissatisfactory about it? I feel like it does everything the OP wants. Also, am I wrong in using `Unconst` over `Unqual`? Isn't `Unqual` overkill if you just want to cast away `const`?
Re: How to pass a class by (const) reference to C++
On Monday, 13 December 2021 at 09:21:26 UTC, Jan wrote: On Monday, 13 December 2021 at 07:48:34 UTC, evilrat wrote: On Sunday, 12 December 2021 at 21:24:39 UTC, Jan wrote: In D I have an extern(C++) class: ```cpp extern(C++) class A { ~this(); // other stuff } ``` An a function that takes A by const reference: ```cpp void CppFunc(const A& arg); ``` But how do I bind this in D ? ```cpp extern(C++) void CppFunc(A arg); // tries to pass as 'A*' extern(C++) void CppFunc(ref const(A) arg); // tries to pass as 'A const * const &' ``` I have solved similar problems with other classes by declaring them as struct in D, but that only works for classes that have no virtual functions. I now have a class where I do need to use a class on the D side, and now I have problems passing these objects to C++. You can tell compiler to mangle it as struct/class using extern(C++, struct). ```d extern (C++, struct) // will use struct mangling even though it's a class class SomeDClass { ... } ``` I tried this, but it doesn't work, because it seems D decides how to pass the object by whether it is a class or struct in D, not in C++. So even with the change as you suggested it, it still tries to pass the object as a pointer to begin with. You'll have to use something called a [shim](https://en.wikipedia.org/wiki/Shim_(computing)), it seems. For example: `main.d` : ```d extern(C++) class A{} extern(C++) void cppFunc_shim(A arg); void main(){ A a = new A(); cppFunc_shim(a); } ``` `cppShim.cpp` : ```c++ class A{}; extern void cppFunc(A const &arg); void cppFunc_shim(A *param){ const A forwardingVar = A(*param); cppFunc(forwardingVar); } ``` `cppFunc.cpp` : ```c++ #include "iostream" class A{}; void cppFunc(A const &arg){ //std::cout << arg << std::endl; std::cout << "Called cppFunc :D" << std::endl; } ``` Then pass the following on the command line(assuming all files are in the same directory): `ldmd2 main.d cppFunc.o cppShim.o -L-lstdc++` That's what it took to make it work for me, dunno if more convenient methods exist. Hope it helps :D
Re: template ctor overload Segmentation fault
On Sunday, 12 December 2021 at 19:17:53 UTC, vit wrote: On Sunday, 12 December 2021 at 18:32:28 UTC, Imperatorn wrote: On Sunday, 12 December 2021 at 11:57:43 UTC, vit wrote: Hello, why does this code fail to compile? ```d struct Foo(T){ this(Rhs, this This)(scope Rhs rhs){ } this(ref scope typeof(this) rhs){ } } struct Bar{ Foo!int foo; } void main(){ } ``` error: Segmentation fault (core dumped) What are you trying to accomplish? Something like this: ```d import std.traits : CopyConstness; struct UniquePtr(T){ alias Type = T; this(Rhs, this This)(scope Rhs rhs) if(is(CopyConstness!(Rhs, Rhs.Type*) : CopyConstness!(This, This.Type*))){ //... } //one of copy ctors: this(ref scope typeof(this) rhs){ //... } static UniquePtr make(Args...)(Args args){ return UniquePtr.init; } } void main(){ const UniquePtr!(int) cui = UniquePtr!(const int).make(1); const UniquePtr!(const int) cuci = UniquePtr!(const int).make(1); UniquePtr!(const int) uci = UniquePtr!(int).make(1); UniquePtr!(int) ui = UniquePtr!(int).make(1); const UniquePtr!(int) xcui = UniquePtr!(immutable int).make(1); const UniquePtr!(const int) xcuci = UniquePtr!(immutable int).make(1); } ``` This work but UniquePtr canno't be inside struct because Segmentation fault. This made your previous snippet work: ```d struct Foo(T){ this(Rhs, this This)(scope Rhs rhs){ } this(scope Foo!(T)* rhs){ } } struct Bar{ Foo!int foo; } void main(){ import std.stdio:writeln; Bar bar = Bar(); auto BAR = new Bar(); writeln(bar, "\t", BAR, "\t", *BAR); } ``` Definitely something funky going on behind the scenes. I also think you should post a bug, like the above user said.
Re: Why code failed to compile for foo2?
On Sunday, 12 December 2021 at 03:02:28 UTC, apz28 wrote: On Sunday, 12 December 2021 at 00:02:25 UTC, Stanislav Blinov wrote: @apz28, I can't figure out the intent here. To convert result of abs to an unsigned? The function logic works only for unsigned type and the parameter value can be altered in body hence Unqual. If not Unqual, must declare a local var and make a copy. Just asking if this can be done to avoid a cast by caller AFAIK stuff like `const int` implicitly converts to `int` since `int` is passed by value so the `const`ness of the original value is not violated. That's why code like: ```d void main(){ const int a = 55; int b = a; } ``` compiles and executes. So, in a similar vein, your code will transform to: ```d void foo1(ubyte x) {} void foo1(ushort x) {} void foo1(uint x) {} void foo1(ulong x) {} import std.traits : Unconst; import std.stdio : writeln; void foo2(T)(T x) if(is(Unconst!(T) : ulong)) {//You don't need Unqual for this foo3(x); } void foo3(ulong param){ //I'm assuming this is your function that you will pass your uint to writeln(param); } void main() { import std.math; int s = int.min + 1; //abs returns int.min for abs(int.min) lol XD foo1(abs(s)); foo2(abs(s)); //failed? //Not anymore :D } ``` Again, please remember that `std.math.algebraic:abs` doesn't return `uint` for `int` and so on, please see [the documentation](https://dlang.org/phobos/std_math_algebraic.html#.abs): Returns: The absolute value of the number. If floating-point or integral, the __return type__ will be the __same as the input__. Limitations Does not work correctly for signed intergal types and value Num.min.