Re: Preventing the Compiler from Optimizing Away Benchmarks
On Monday, 13 March 2023 at 14:17:57 UTC, jmh530 wrote: I was looking at [1] for ways to prevent the compiler from optimizing away code when trying to benchmark. It has the following C++ code as a simpler version: ``` inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) { asm volatile("" : "+r,m"(value) : : "memory"); } ``` I made an attempt to make a D version of it, but failed. Apparently DMD doesn't like the `""` in the first part of the asm instruction. I'm also not sure the `volatileLoad` command is right, but I didn't know of any other way to have volatile work in D (and I couldn't figure out how it actually worked from looking at the code). ``` void DoNotOptimize(T)(T* ptr) { import core.volatile: volatileLoad; T value = volatileLoad(ptr); asm {"" : "+r,m"(value) : : "memory";} } ``` [1] https://theunixzoo.co.uk/blog/2021-10-14-preventing-optimisations.html that's illegal code. You mix GCC/LLVM syntax with D asm block and the front-end wont recognize that. LDC recognizes a syntax similar to what is described in your link, see https://wiki.dlang.org/LDC_inline_assembly_expressions. GDC has it too (since that the syntax invented by GCC in first place) but I cant find the documentation ATM.
Re: Can nice D code get a bit slow?
On Wednesday, 8 March 2023 at 12:46:53 UTC, Hipreme wrote: On Wednesday, 8 March 2023 at 10:49:32 UTC, Markus wrote: Hi, sorry for the broad and vague question. I have read in some reddit post about benchmarks, that some code didn't use the final keyword on methods in a sense that final would make it faster, I believe. [...] Don't bother with it. This kind of optimization is done when compiling with -O, No they are not, simple example : https://godbolt.org/z/xfPqnWrrv Obviously in a library `test` might be called with a derived so `v1()` target address must be read in the vtbl of the argument. and I really doubt about your bottleneck being that you're calling a virtual call. That is more true. vcalls dont add complexity. Wait when you actually need to optimize before making your code ugly.
Re: Template alias parameter: error: need 'this' for ...
On Friday, 24 February 2023 at 12:00:41 UTC, Elfstone wrote: Seems like the same bug is still there after ten years. ```d struct Bar { @("hello") int t; } static bool hasAttribute(alias F, T)() { bool result = false; foreach (a; __traits(getAttributes, F)) { static if (is(typeof(a) : T)) { result = true; // couldn't simply return true, 'cause the compiler complains about "unreachable code". } } return result; } void main() { import std.stdio; writeln(hasAttribute!(Bar.t, string)); } ``` you can break using `goto`, restore `static` everywhere, and using local introspection determine whether the result exists. ```d struct Bar { @("hello") int t; } static bool hasAttribute(alias F, T)() { static foreach (a; __traits(getAttributes, F)) { static if (is(typeof(a) : T)) { enum result = true; goto L0; } } L0: static if (is(typeof(result))) return result; else return false; } void main() { import std.stdio; writeln(hasAttribute!(Bar.t, string)); } ```
Re: ELIZA Chatbot Implementation From C to D Lang
On Friday, 17 February 2023 at 17:03:34 UTC, ron77 wrote: Hello, I succeeded in converting an ELIZA code from C to D, and here are the results. although I'm sure there are better ways to code it or to convert it... [...] Among the things to do the first is to drop C-style strings, so that you can get rid of `strlen()` and `strcat()` for example. Then maybe try to rewrite your for-loops as UFCS pipes. Have fun.
Re: compile: link dynamic OR static library in Windows
On Sunday, 5 February 2023 at 11:52:01 UTC, Alexander Zhirov wrote: On Saturday, 4 February 2023 at 15:56:41 UTC, Richard (Rikki) Andrew Cattermole wrote: [...] I don't understand why the compiler doesn't see the library. ```sh User@WIN-D3SHRBHN7F6 MINGW64 /home/user/pxe-restore/source # ls -la "C:\Program Files\PostgreSQL\15\lib\libpq.lib" -rw-r--r-- 1 User Отсутствует 37002 Nov 9 06:45 'C:\Program Files\PostgreSQL\15\lib\libpq.lib' User@WIN-D3SHRBHN7F6 MINGW64 /home/user/pxe-restore/source # dmd -i app.d -L'C:\Program Files\PostgreSQL\15\lib\libpq.lib' lld-link: error: could not open 'pq.lib': no such file or directory Error: linker exited with status 1 ``` try ``` dmd -i app.d -L'-LC:\Program Files\PostgreSQL\15\lib' -Llpq ``` the first linker command gives a search path, the second a libname.
Re: _Symbols _with _leading _underscores
On Saturday, 17 December 2022 at 02:42:22 UTC, Paul wrote: I see code like this from time to time. Are the leading underscores significant, in general, in the D language? Is it just programmer preference? Is it a coding practice, in general, that is common...even outside of D? Thanks for any assistance. The only important thing you should know about is that doubly leading underscores are reserved for symbols generated by the D front-end, so you should avoid them. This is specified here: https://dlang.org/spec/lex.html#identifiers.
Re: How to pass noncopyable variadic arguments with ref?
On Thursday, 20 October 2022 at 16:34:34 UTC, user1234 wrote: On Thursday, 20 October 2022 at 14:03:10 UTC, tchaloupka wrote: Hi, I've found strange behavior where: [...] Shouldn't it at least protest that objects can't be passed to the function as they aren't copyable? it's clearly a compiler bug to me. Something is not checked when the call is verified. however (forgot to say) this form of variadic was proposed for deprecation. So maybe the bug is more an argument to drop them.
Re: How to pass noncopyable variadic arguments with ref?
On Thursday, 20 October 2022 at 14:03:10 UTC, tchaloupka wrote: Hi, I've found strange behavior where: [...] Shouldn't it at least protest that objects can't be passed to the function as they aren't copyable? it's clearly a compiler bug to me. Something is not checked when the call is verified.
Re: Generate a pointer to a method of a struct
On Saturday, 15 October 2022 at 01:48:15 UTC, kdevel wrote: Is this consistent? I think all the compilers should error on expressions like `Type.nonStaticMethod` and instead there should be a new __traits dedicated to that, especially because `this` is not a formal parameter.
Re: How to workaround assignment not allowed in a condition?
On Wednesday, 12 October 2022 at 02:15:55 UTC, Steven Schveighoffer wrote: Porting some C code to D This results in an error: ```d int x; while(!(x = 5)) { break; } ``` Error is: assignment cannot be used as a condition, perhaps `==` was meant? ... I think D should relax the restriction and allows the AssignExp as condition they are enclosed between parentheses.
Re: Example for multi level template composition
On Monday, 10 October 2022 at 06:30:05 UTC, Arun wrote: Stumbled upon this question on HN https://news.ycombinator.com/item?id=33142751#33147401 Can I write template A and then apply it to itself to get template B and then apply that onto template C to get template D. Does anyone have an example for this? Recursive templates can make other templates with themselves. I dont feel to provide an example ATM tho.
Re: Explicit cast to @system?
On Saturday, 8 October 2022 at 23:06:13 UTC, Anonymouse wrote: I have some nested templated code that takes function pointers. In many cases I pass it functions of identical signatures, except some are `@safe` and others are `@system`. In those cases the templates end up getting instantiated twice. I don't care about the `@safe`-ness and I'd really like to just have them all treated as `@system`, with one instantiation per unique signature. To illustrate: [...] ...but there are a lot of different signatures and I need a general approach. There doesn't seem to be such a thing as `cast(@system)fp`. My current solution involves some very gnarly string mixins. I see what you mean, in the past I wanted `cast(pure)`, `cast(nothrow)`, similarly to avoid using metaprog (or maybe was that delegates) in certain case. [...] But surely there has to be a better way? No.
Re: cannot gdb LDC build binary: Segmentation fault
On Friday, 7 October 2022 at 04:40:34 UTC, mw wrote: Hi, I have a LDC (1.30.0) built binary on Ubuntu 18.04.5 LTS x86_64, the program core dumps somewhere, so I want to debug it. However under gdb, the program fails as soon as I start it: [...] Try the non-stop mode maybe : https://sourceware.org/gdb/onlinedocs/gdb/Non_002dStop-Mode.html
Re: to delete the '\0' characters
On Thursday, 22 September 2022 at 10:53:32 UTC, Salih Dincer wrote: Is there a more accurate way to delete the '\0' characters at the end of the string? I tried functions in this module: https://dlang.org/phobos/std_string.html ```d auto foo(string s) { string r; foreach(c; s) { if(c > 0) { r ~= c; } } return r; } ``` SDB@79 Two remarks: 1. The zero implicitly added to literals is not part of the string. for example s[$-1] will not give 0 unless you added it explictly to a literal 2. you code remove all the 0, not the one at the end. As it still ensure what you want to achieve, maybe try [`stripRight()`](https://dlang.org/phobos/std_string.html#.stripRight). The second overload allows to specify the characters to remove.
Re: Validate static asserts
On Friday, 9 September 2022 at 17:35:44 UTC, Dennis wrote: On Friday, 9 September 2022 at 16:41:54 UTC, Andrey Zherikov wrote: What's about new `compileOutput` trait that returns compiler output? ```d static assert(__traits(compileOutput, { }) == "message"); ``` As a compiler dev, that sounds terrifying. It would make basically every change to dmd a breaking change. Ah yes, it is so stupid that error message are part of the semantics
Re: Programs in D are huge
On Tuesday, 16 August 2022 at 08:25:18 UTC, Diego wrote: Hello everyone, I'm a Java programmer at work but i'm learning D for pleasure. I'm reading _The D Programming Language by Ali Çehreli_. I noticed that DMD creates very huge executable, for example an empty program: ``` empty.d: void main() { } ``` after a compilation with these flags `dmd -de -w empty.d` i have an executable of 869KiB It seams huge in my opinion for an empty program What are the best practices to reduce the size? This is normal, by default you have plenty of typeinfo (static data allowing dynamic introspection), code located in implicit import object.d, the runtime (e.g code for the GC). You can really get rid of that, excepted using -betterC, but you see all the stuff that make the default main program big will actually be useful in a real program. It's just that D is not as much "pay as you go" as that, for now.
Re: code review: splitIds from DConf '22 day 3: saving a sort and "getting performance"
On Thursday, 4 August 2022 at 13:18:40 UTC, kdevel wrote: At DConf '22 day 3 Robert Schadek presented at around 07:22:00 in the YT video the function `splitIds`. Given an HTML page from bugzilla containing a list of issues `splitIds` aims at extracting all bug-ids referenced within a specific url context: ``` long [] splitIds (string page) { enum re = ctRegex!(`"show_bug.cgi\?id=[0-9]+"`); auto m = page.matchAll (re); return m .filter!(it => it.length > 0) // what is this? .map!(it => it.front) // whole match, it[0] .map!(it => it.find!(isNumber)) // searches fist number .map!(it => it.until!(it => !it.isNumber ())) // last number .filter!(it => !it.empty) // again an empty check??? why? .map!(it => it.to!long ()) .uniq // .sort is missing. IMHO saving at the wrong things? .array; } ``` `m` contains all matches. It is a "list of lists" as one would say in Perl. The "inner lists" contains as first element ("`front`") the string which matches the whole pattern. So my first question is: What is the purpose of the first filter call? Since the element of `m` is a match it cannot have a length of 0. [...] I think that the first one is to prevent to call `front()` on an empty range, excepted that according to the regex that should not happen. BTW I haven't washed the video but I suppose this is related to the migration of bugzilla to GH issues. I wonder why https://bugzilla.readthedocs.io/en/5.0/api/index.html#apis is not used instead.
Re: Build for i586
On Thursday, 28 July 2022 at 06:12:49 UTC, Alexander Zhirov wrote: On Thursday, 28 July 2022 at 06:01:17 UTC, Alexander Zhirov > x86- 32-bit X86: Pentium-Pro and above I also tried with `i586` and `pentium` - the result is the same. Pentium Pro and above means at least i686. i586 is Pentium1 which is less featured. That means that you cant do much, however you can try to tune the i686 target and disable emiting of the instructions that were added from the Pentium Pro. Maybe that the produced instruction will then be compatible. that would be something like `--mcpu=i686 --mattrs=-mmx,-sse` and maybe more to be sure. Other things: "Registered Targets: ... " means that maybe the LDC developers could add the i586 target but did not consider useful to add this is old processor (e.g Pentium1). For that you should ask them if you can and how activate the target when you build ldc2 on your old Geode.
Re: Build for i586
On Thursday, 28 July 2022 at 07:16:13 UTC, user1234 wrote: On Thursday, 28 July 2022 at 06:12:49 UTC, Alexander Zhirov wrote: [...] Pentium Pro and above means at least i686. i586 is Pentium1 which is less featured. That means that you cant do much, however you can try to tune the i686 target and disable emiting of the instructions that were added from the Pentium Pro. Maybe that the produced instruction will then be compatible. that would be something like `--mcpu=i686 --mattrs=-mmx,-sse` and maybe more to be sure. Other things: "Registered Targets: ... " means that maybe the LDC developers could add the i586 target but did not consider useful to add this is old processor (e.g Pentium1). For that you should ask them if you can and how activate the target when you build ldc2 on your old Geode. ask here https://forum.dlang.org/group/ldc for better answers
Re: null == "" is true?
On Tuesday, 12 July 2022 at 19:55:46 UTC, ag0aep6g wrote: On Tuesday, 12 July 2022 at 19:02:01 UTC, user1234 wrote: On Tuesday, 12 July 2022 at 16:40:38 UTC, H. S. Teoh wrote: [...] Do not rely on this, however; Absolutely. I'd like to add: especially as default parameter value that's an array. Never use null. use `[]` (empty array literal). Just to be clear: `[]` and `null` are the exact same thing (null pointer, zero length). The reason to prefer `[]` over `null` is purely for readability. The meaning is exactly the same. ah yes. The case I thought to was actually ```d void test1(string s = null) { assert(s is null); } void test2(string s = "") // s is null term'ed, i.e not null { assert(s is null); } void main() { test1(); test2(); // fails } ``` the rule of thumb is to use `stuff.length` as condition, always, and not `stuff` itself, to prevent natyx, hard to find bugs.
Re: null == "" is true?
On Tuesday, 12 July 2022 at 16:40:38 UTC, H. S. Teoh wrote: On Tue, Jul 12, 2022 at 04:27:44PM +, Antonio via Digitalmars-d-learn wrote: It works ```d void main() { assert(null==""); } ``` why? Because an empty string is, by default, represented by an empty slice of the null pointer. Do not rely on this, however; Absolutely. I'd like to add: especially as default parameter value that's an array. Never use null. use `[]` (empty array literal).
Re: How to check if something can be null
On Friday, 1 July 2022 at 13:53:28 UTC, Antonio wrote: On Friday, 1 July 2022 at 13:48:25 UTC, Antonio wrote: -Why? I realized Json is an struct (not an object)... and I supose, it is managing null asignation manually (as a way to build Json(null)). -Whats the correct whay to test if something can be null? That's my question :-p Something like this does the job: ```d enum canBeNull(T) = is(typeof({T t; t = null;})); static assert(canBeNull!(Object)); static assert(!canBeNull!(int)); ``` and that should handle opAssign and opCmp overloads.
Re: Bug in dmd?
On Tuesday, 14 June 2022 at 13:39:12 UTC, Andrey Zherikov wrote: I have [pretty simple code in my library](https://github.com/andrey- [Line (2) produces](https://github.com/andrey-zherikov/argparse/runs/6880350900?check_suite_focus=true#step:5:12) `undefined reference to '_D3std7sumtype__T7SumTypeTS8argparse4help2AATSQtQm2BBZQBl6__dtorMFNaNbNiNfZv'` (it demangles to `pure nothrow @nogc @safe void std.sumtype.SumType!(argparse.help.AA, argparse.help.BB).SumType.__dtor()`) If I comment line (2) then everything is good (no link errors). Note that there is the same code at (1) which doesn't produce any error. Any idea what's going on? That can be a template instance that's emitted somewhere else, i.e the thing is there but the mangle is different. maybe try to find if the dtor is there with `mn -S` on each object. Another thing to try in these situations is to see if that works with `-allinst`.
Re: Generating unique identifiers at compile time
On Monday, 13 June 2022 at 07:38:54 UTC, user1234 wrote: On Thursday, 9 June 2022 at 23:50:10 UTC, user1234 wrote: On Thursday, 9 June 2022 at 21:20:27 UTC, JG wrote: [...] No, for now there if there are other ways they are as hacky as yours. The compiler usually uses a global counter to generate temporaries. There's [been attempts] to expose it, exactly so that users can generate unique names, but that did not found its path in the compiler. [been attempts]: https://github.com/dlang/dmd/pull/10131 Here's another one. That's nice if people are able to find tricks but there's a need to have a clean way to do that. i.e language feature. Damnit, forgot [the link] [the link]: https://github.com/dlang/dmd/pull/5633
Re: Generating unique identifiers at compile time
On Thursday, 9 June 2022 at 23:50:10 UTC, user1234 wrote: On Thursday, 9 June 2022 at 21:20:27 UTC, JG wrote: [...] No, for now there if there are other ways they are as hacky as yours. The compiler usually uses a global counter to generate temporaries. There's [been attempts] to expose it, exactly so that users can generate unique names, but that did not found its path in the compiler. [been attempts]: https://github.com/dlang/dmd/pull/10131 Here's another one. That's nice if people are able to find tricks but there's a need to have a clean way to do that. i.e language feature.
Re: Generating unique identifiers at compile time
On Thursday, 9 June 2022 at 21:20:27 UTC, JG wrote: Hi, As an experiment I have implemented the following kind of pattern matching (by parsing the part of the string before '='). ```d struct S { int x; int y; } struct T { int w; S s; } void main() { mixin(matchAssign(q{auto T(first,S(second,third)) = T(1,S(2,3));})); first.writeln; // 1 second.writeln; // 2 third.writeln; // 3 } ``` In doing so I wanted to produce unique identifiers (something like gensym in racket.) I did this in a very hacky way: ```d auto hopefullyUniqueName(size_t n, size_t line=__LINE__) { return format!"var___%s%s"(n,line); } ``` where I pass in the hash of the right hand side in the assignment in place of n. Is there some way to ask the compiler for a unique name or a better way of achieving this? No, for now there if there are other ways they are as hacky as yours. The compiler usually uses a global counter to generate temporaries. There's [been attempts] to expose it, exactly so that users can generate unique names, but that did not found its path in the compiler. [been attempts]: https://github.com/dlang/dmd/pull/10131
Re: Why is the compiled file size so huge?
On Friday, 27 May 2022 at 13:40:25 UTC, Alexander Zhirov wrote: I'm trying to compile a file that weighs 3 kilobytes. I'm also linking a self-written dynamic library. I don't understand why the resulting executable file is so huge? After all, all libraries are present: I'd take a look with IDA or hydra to check the details (maybe something is statically linked after all, that should be visible by inspecting the names view) but one thing to understand in a first time is that 1. even if druntime and phobos are dynamic libraries all the template instances are generated in your binary. 2. use of some module has for effect to create huge static tables. I think to all the UTF stuff and also std regex.
Re: Inferred attributes errors in template function.
On Friday, 27 May 2022 at 09:41:32 UTC, user1234 wrote: [...] on a side note that's funny how dmd manages to systematically print the less interesting message in both case. They are actually correct, I dont know why at some point I thought there was a problem. For the float one it's oviously not pure and for the int one it's not safe... OP wants better error message.
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` } ``` [...] on a side note that's funny how dmd manages to systematically print the less interesting message in both case.
Re: Cannot check function address
On Wednesday, 25 May 2022 at 06:04:10 UTC, frame wrote: On Wednesday, 25 May 2022 at 05:56:28 UTC, Steven Schveighoffer wrote: It's a case where the compiler can't divine what you were thinking when you wrote that code ;) I see not in all cases but in mine. If the compiler sees the function isn't callable without arguments and it is inside an if-statement or `assert()` then it could at least suggest a pointer or ask: are you dumb? ;-) As suggested by others, the reduction is not correct, you have stripped too muchbecause this compiles just fine: a.d: ```d alias F = void function(int); F f; static this() { assert(!f); assert(f is null); } ``` b.d: ```d import a; static this() { assert(!f); assert(f is null); } ``` ```sh $ dmd a.d b.d -main $ echo $? $ 0 ```
Re: Odd construct idea. Splitting arguments inside a parameter list.
On Monday, 23 May 2022 at 08:53:27 UTC, user1234 wrote: On Monday, 23 May 2022 at 08:52:12 UTC, vit wrote: On Monday, 23 May 2022 at 08:34:21 UTC, Chris Katko wrote: D struct pair { float x,y; } [...] This work too: ```d myFunction(taco, p.tupleof, burrito); ``` and you can pass a std.typecons.Tuple as well, it will expand x y well actually std Tuple is a struct but that works without excplicit `.tupleof`.
Re: Odd construct idea. Splitting arguments inside a parameter list.
On Monday, 23 May 2022 at 08:52:12 UTC, vit wrote: On Monday, 23 May 2022 at 08:34:21 UTC, Chris Katko wrote: D struct pair { float x,y; } [...] This work too: ```d myFunction(taco, p.tupleof, burrito); ``` and you can pass a std.typecons.Tuple as well, it will expand x y
Re: template? mixin? template mixins? for modifying a struct setup
On Thursday, 19 May 2022 at 10:15:32 UTC, Chris Katko wrote: given ```D struct COLOR { float r, g, b, a; // a is alpha (opposite of transparency) } auto red = COLOR(1,0,0,1); auto green = COLOR(0,1,0,1); auto blue = COLOR(0,0,1,1); auto white = COLOR(1,1,1,1); //etc ``` is there a way to do: ```D auto myColor = GREY!(0.5); // where GREY!(0.5) becomes COLOR(0.5, 0.5, 0.5, 1.0); ``` average is a bad way to grayscale FYI ;)
Re: String Literals
On Tuesday, 3 May 2022 at 17:21:47 UTC, JG wrote: Hi, The specification of string literals has either some errors or I don't understand what is meant by a Character. [...] Which to me means that e.g. r""" should be a WysiwygString, which the compiler thinks is not (not surprisingly). Am I misunderstanding something? The rule is not correct but the implementation in the lexer is. That's a valid issue for dlang.org
Re: generic function instance without call
On Wednesday, 27 April 2022 at 17:22:14 UTC, vit wrote: This work for types but not for attributes like `scope`, `return` and `auto ref`. Oh sorry... auto ref... I totally forgot [this old bug] [this old bug]: https://issues.dlang.org/show_bug.cgi?id=8204
Re: generic function instance without call
On Wednesday, 27 April 2022 at 15:23:26 UTC, vit wrote: Hi, is it possible to get address of generic function instance for specified arguments without calling the function? Example: ```d auto foo(alias fn, Args...)(auto ref Args args){ ///return function/delegate type of `fn` for arguments `args` } void main(){ long x; auto fn = foo!((a, b) => true)(new int(42), x); static assert(is(typeof(fn) == bool function(int*, scope ref long)@safe pure nothrow @nogc )); } ``` yeah sure; declare an alias that (fully) specialize the generic func and take the address using the alias Identifier.
Re: A template construct like using()
On Tuesday, 26 April 2022 at 21:33:43 UTC, Chris Katko wrote: I swear I asked something like this before years ago but it doesn't show up in my previous forum posts. I'm looking for a construct that mimics using(var)/with(var) ```D bitmap* b; draw_with(b) { draw_pixel(red, 16, 16); //draw red pixel to bitmap b (b is implied above) } ``` But the code ends up being: ```D bitmap* b; set_target_bitmap(b); //entry code draw_pixel(red, 16, 16); // body set_target_bitmap(original_target); // exit code ``` The essence is wrapping something the code up in a kind of RAII-like entry and exit code that references a given target variable. Perhaps a mixin is what I'm looking for? assuming `set_target_bitmap` returns the previous target : ```d struct Bitmap { } struct PushPopBitmap { Bitmap* bitmap; Bitmap* old; alias bitmap this; this(Bitmap* bmp) { old = set_target_bitmap(bitmap = bmp); } ~this() { set_target_bitmap(old); } } Bitmap* set_target_bitmap(Bitmap* bmp); void draw_pixel(); void main() { Bitmap* bmp; with (PushPopBitmap(bmp)) draw_pixel(); } ``` At the end of the WithStatement block that restores the previous context.
Re: Create a wrapper around larger c-libraries
On Sunday, 24 April 2022 at 15:13:15 UTC, Alain De Vos wrote: I'm currenlty experimenting about binding to C. I have : C-library: mylib.h: ``` void libprintme(char *s); ``` mylib.c: ``` #include #include "mylib.h" void libprintme(char *s){printf("%s",s);} ``` [...] Can this procedure be used for larger C-libraries ? What is good , what is bad , what can be better. Feel free to elaborate ? (It's the C-preprocessor with macro expansion which gives me sometimes a bit of a headache.) Why not just ```d extern(C) @nogc nothrow { void libprintme(char *s); alias cprintme = libprintme; } ``` ? The function pointer looks totally superfluous to me.
Re: Static struct initialization syntax behavior & it being disabled upon adding a constructor
On Monday, 18 April 2022 at 10:26:16 UTC, HuskyNator wrote: On a sidenote, I'm surprised D did not choose 0 as the default floating value. Doesn't almost every language do this? I understand the thinking behind it, but when the type one uses in a template influences the behavior of the code, that seems like a pretty big red flag to me. (Any non-floating type defaults to 0, but using floats/doubles suddenly introduces NaN, surely I'm not the only one that sees a problem with this ) Especially when it's basically a standard 0 is used for this. Sorry for the rant. Let me explain the why: D default initialization is not designed to replace user-defined initialization, it's rather made to make bugs related to non-initialized variables stable, e.g not UB. The easiest way to get that is to think to references and pointers. A random garbage value pointed by an alloca may work to some point (e.g access to member), if it's set to `null` right after the alloca then you have a stable segfault that always happens at the same time and is easy to debug. Similarly, for floating point numbers the D designers considered that `NaN` was the best choice because FP operations will not wrongly appear valid when starting operations with NaN. With integral types, this system does not work as well, as `0` doesn't create bugs as easily as `null` and `NaN`. The confusion about the real role of default initialization comes from integral types I believe.
Re: How to use Vector Extensions in an opBinary
On Sunday, 17 April 2022 at 11:16:25 UTC, HuskyNator wrote: I recently found out there is [support for vector extensions](https://dlang.org/spec/simd.html) But I have found I don't really understand how to use it, not even mentioning the more complex stuff. I couldn't find any good examples either. I'm trying to figure out how to implement the following opBinary using vector extensions. ```dlang alias MatType = typeof(this); union{ T[rows*columns] vec; T[rows][columns] mat; } MatType opBinary(string op, T)(const T right) const { MatType result = this; mixin("result.vec[] = this.vec[] " ~ op ~ " right;"); return result; } ``` Or alternatively, as I'm not sure which is more efficient/faster: ```dlang MatType opBinary(string op, T)(const T right) const { MatType result; static foreach(i; 0..rows*columns) mixin("result.vec[i] = this.vec[i] " ~ op ~ " right;"); return result; } ``` But going off the documentation, I have no idea how to use vector extensions to achieve something like this. As a small disclaimer; I don't know to what extent the compiler already automates these kind of operations, and mostly want to use this as a learning experience. Kind regards, HN I'd experiment with CompilerExplorer. For example [this](https://godbolt.org/z/a51r8GEv4) shows that the codegen is identical for both opBinary version for "+". About time spent to compile, `static foreach` is known not to scale well.
Re: Lambdas Scope
On Monday, 11 April 2022 at 09:11:06 UTC, Salih Dincer wrote: How is this possible? Why is it compiled? Don't the same names in the same scope conflict? ```d int function(int) square; void main() { square = (int a) => a * a; int square = 5.square; assert(square == 25); } ``` Thanks, SDB@79 you can use explicit call parenthesis to make the difference between the local var and the global func. Also you have the module access operator and the fully qualified name as alternatives to select the one you wish to.
Re: Why do immutable variables need reference counting?
On Sunday, 10 April 2022 at 23:05:24 UTC, norm wrote: Hi All, I am clearly misunderstanding something fundamental, and probably obvious :D Reading some of the discussions on __metadata I was wondering if someone could explain why a immutable reference counting type is needed. By definition a reference counter cannot be immutable, so what would be the use case that requires it? It cannot really be pure nor safe either because the ref goes out of scope and the allocation is freed. How is this immutable? Thanks, Norm refcounting would require a concept of "tail const" / "tail immutable" so that transitivity of the qualifier does not affect the data used to refcount (basically the field that hold the count) but only the data that **are** refcounted.
Re: Where I download Digital Mars C Preprocessor sppn.exe?
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
Re: Nested Classes with inheritance
On Saturday, 19 March 2022 at 05:25:01 UTC, Era Scarecrow wrote: On Saturday, 19 March 2022 at 00:16:48 UTC, user1234 wrote: That crashes because of the creation of `Bar b` member, which itself has a Bar b member, which itself... Mhmm... So There's Foo with Bar b, which has Bar b which has Bar b which... just keeps going over and over again. It appears to me that it only crashes when you fully run out of memory then. Much like a function calling itself and you exhaust all your stack space. I'd suggest avoiding self-inheritance. No one wants to be their own Grandpa I think OP is learning OOP. His error looks like that for the least.
Re: Nested Classes with inheritance
On Saturday, 19 March 2022 at 00:05:54 UTC, Salih Dincer wrote: Greetings to all... There are nested classes as below. But beware, there's also inheritance, extra! If you construct ```Bar b``` from main(), it's okay. But if declare the constructor in Foo(), the program crashes with a segmentation error. Is this not legal? Like two mirrors are facing each other, that I do? ```d class Foo { Bar b; int i; this(int n) { this.i = n; //this.b = new Bar(this.i); // compiles but crashes } class Bar : Foo { int i; this(int n) { this.i = n; super(this.i); } } } void main() { auto foo = new Foo(1); auto bar = foo.new Bar(1); foo.b = bar; assert(foo.i == foo.b.i); } ``` SDB@79 That crashes because of the creation of `Bar b` member, which itself has a Bar b member, which itself... One solution is to create the member depending on some condition, example: ```d if (typeid(this) !is typeid(Bar)) this.b = new Bar(this.i); ```
Re: static init c struct with array filed
On Wednesday, 16 March 2022 at 14:42:02 UTC, Era Scarecrow wrote: On Wednesday, 16 March 2022 at 11:27:20 UTC, user1234 wrote: assuming the c library takes by reference My experience all arrays are effectively just pointers I meant the function that takes the Test2 as parameter, but to be honest I dont get exactly what does OP want actually... that's true that passing a Test2 is somewhat strange as there's no info for the array length.
Re: static init c struct with array filed
On Wednesday, 16 March 2022 at 07:27:06 UTC, test wrote: ```c struct Test { int32_t a; } struct Test2 { int32_t a; Test arr[]; } ``` I need static const init Test2, then pass it to c library late(third library, can not change the type def). I am not sure how to do it in D. ```d extern(C) struct Test { int a; } extern(C) struct Test2 { int a; Test* arr; } static const Test2 t2 = Test2(2, null); void main(){ to_c_library(); to_c_library(new Test2(2, null)); Test2 local; to_c_library(); } ``` assuming the c library takes by reference
Re: initializing struct containing user defined type
On Friday, 18 February 2022 at 23:46:51 UTC, forkit wrote: On Friday, 18 February 2022 at 16:45:24 UTC, Ali Çehreli wrote: ... I think that syntax will be obviated when D will have named arguments. Ali Huh? D doesn't have named arguments, already? That's an important component for safe(r) programming. Do you know if there is a DIP for this, and if so, it's current status. The DIP is [accepted] but not implemented. [accepted]: https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1030.md
Re: Filling an array at compile time
On Wednesday, 9 February 2022 at 10:25:34 UTC, bauss wrote: Is it guaranteed that the value is initialized at compiletime however? yes, D guarentees this at 100%.
Re: how to handle very large array?
On Wednesday, 9 February 2022 at 10:29:03 UTC, ag0aep6g wrote: Try to think of a more efficient way of storing the information. I cant agree more. The problem of OP is not dynamic arrays, it's that he uses an inadequate data structure.
Re: template ctor overload Segmentation fault
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) Firstly, report the crash with the keyword "ice". Then, there might be something not allowed (in some situations the compiler cant decide which ctor to use) but you cant see it for now.
Re: Debugging D code with GDB
On Sunday, 28 November 2021 at 16:44:38 UTC, russhy wrote: On Sunday, 28 November 2021 at 14:53:17 UTC, user1234 wrote: ... there is a plugin to demangle things automatically https://github.com/ANtlord/gdb-ddemangle That's off-topic. The point here is that you can (unfortunately) **only** evaluate the call using the mangled form, it's not about transforming the output. Actually what would be useful is a plugin the mangle the call in custom expression before passing it to gdb ;)
Re: Debugging D code with GDB
On Saturday, 27 November 2021 at 14:17:11 UTC, Eduard Staniloiu wrote: Hello, I'm trying to use `gdb` to debug D binaries, but I'm having trouble accessing the methods of a struct or class. It seems that `gdb` doesn't see them. [...] Looking forward to your answers, Edi [0] - https://sourceware.org/bugzilla/show_bug.cgi?id=22480 Hello, while I never evaluate calls during debugging I've managed to find a way : you can call the mangled name so for ```d #!dmd -g module a; import std.stdio; struct S { int myPrint(){return 8;} } pragma(msg, S.myPrint.mangleof); int main(string[] args) { S s; return 0; } ``` in gdb CLI ```bash p (int) _D1a1S7myPrintMFZi(s) $1 = 8 ``` works. Note that for some reasons writefln causes a crash, that's why I've modified the example. The problem is that my workaround does not scale better than your.
Re: New developments on topic of memset, memcpy and similar
On Saturday, 27 November 2021 at 11:15:45 UTC, Igor wrote: Two years ago there was a [Google Summer of Code project](https://forum.dlang.org/thread/izaufklyvmktnwsrm...@forum.dlang.org) to implement these primitives in pure D for various reason. It was concluded the project isn't viable and was abandoned, but there were some interesting learnings. I now stumbled on some new work in C land about these that might be interesting to people that were following the original project so I am sharing it here: Custom ASM implementation that outperforms libc: https://github.com/nadavrot/memset_benchmark Paper on automatic implementation of these primitives: https://dl.acm.org/doi/pdf/10.1145/3459898.3463904 Also LLVM has intrinsics or special instructions for those libc stuff. I suppose that there are special optimz that are tried and if not possible that falls back to the libc version.
Re: How to get the location (file, line) of UDA without parens?
On Sunday, 14 November 2021 at 05:12:58 UTC, Andrey Zherikov wrote: Here is my code: [...] `W()` (2) works as expected but is it possible to achieve the same without parenthesis so `getAttributes` trait returns `tuple(L("app.d", 16LU))` for (1)? No, without parens this is really the function template, as a symbol, that becomes the UDA.
Re: The type inference everywhere
On Sunday, 31 October 2021 at 17:51:45 UTC, data pulverizer wrote: On Sunday, 31 October 2021 at 17:35:35 UTC, Ali Çehreli wrote: On 10/31/21 7:07 AM, Salih Dincer wrote: > [...] because I > [...] Makes sense because e.g. the following works: struct S { auto i = 42; } I bet the problem with your proposal is "auto" in that position is a part of the two-word "auto ref" parameters. I don't know how hard or impossible it would be to allow just "auto" there. In any case, although it would be nice for completeness, the use case is so rare that I wouldn't mind repeating the type twice in that usage. But I agree with you... Ali This is a teachable moment for me, so I'll ask the question. Why isn't something like this the answer? ``` import std.stdio: writeln; struct Section { int x; int y; } auto foo(T)(int value, auto ref T s = Section(2, 60)) { //... return Section(0, 60); } void main() { foo(5).writeln; } ``` To me it is the right answer. Maybe that OP wanted the TemplateType parameter to be implicitly added (and that's why Ali interpreted the question as a language proposal)?
Re: Why do we have Dmain?
On Friday, 22 October 2021 at 05:54:21 UTC, Kirill wrote: I am not a compiler expert, but I genuinely would like to know why we have Dmain. I've been looking at the generated assembly code recently and noticed the _Dmain function. I didn't notice it before. Then there is main, where Dmain is called. Why is that? in addition to the other answers, there's also the parameters of main: int argc, char** argv becomes string[] so with the D main you're directly in the the D "domain". In theory from that point, you don't need to ever use `strlen` for example.
Re: How can we allow using phobos with asserts/contracts?
On Sunday, 17 October 2021 at 21:00:19 UTC, Steven Schveighoffer wrote: On 10/16/21 6:47 PM, solidstate1991 wrote: When I make this call ``` format(" %3.3f"w, avgFPS); ``` my program immediately crashes with an access violation error. The debugger out is different between x86 and x86-64. I've made all sanity checks, so I need some other suggestions. FYI, solidstate figured this out. It was because of an out-of-bounds index on `BitArray`. But that irks me. Why wouldn't `BitArray` do a bounds check? And then I remembered -- Phobos is built in release mode even when your app is not. I literally *cannot* request from the compiler that `BitArray` enforce its contracts without rebuilding the library completely. I never want to build code that doesn't have bounds checks. How can we fix this? -Steve contracts ? bound checks should be in the body and conditionally compiled with `version(D_NoBoundsChecks){} else {}` then same problem because it's not a function template I guess. someone should make it a function template then.
Re: toString and code coverage...
On Wednesday, 22 September 2021 at 15:27:23 UTC, wjoe wrote: Is there a convenient way to exclude it from coverage ? Because adjusting the -cov=xx percentage is kind of annoying and may omit other things as well. Do you care and if yes how do you handle it ? You have several options 1. conditional compilation make toString not existing if instrumentation for coverage is enabled: ```d version(D_Coverage) @disable string toString(); else string toString(){...} ``` 2. use `toString` in a `unittest` that does nothing ```d unittest { static foreach (T; AliasSeq!(StuffWithToString)){ { T t = new T; // or T t; t.toString(); }} } ``` I'd use option 2. For example I already employ this technic to cover string generator functions used in `mixin()` for example. Also in case `toString` is finally a bit used the option 1 will be hard to manage.
Re: Which operators cannot be overloaded and why not?
On Monday, 13 September 2021 at 18:06:42 UTC, NonNull wrote: On Monday, 13 September 2021 at 14:42:42 UTC, jfondren wrote: On Monday, 13 September 2021 at 14:33:03 UTC, user1234 wrote: - condition al expression ` cond ? exp : exp ` And many other boolean operators, unary !, binary && and || https://dlang.org/spec/operatoroverloading.html lists all the overloadable operators, and https://dlang.org/spec/expression.html has all the operators, so "which operators" is a matter of close comparison. Is there no list of such in an article online? It would be good if that work was done for once and for all, with a short explanation in each case, possibly with discussion in some cases of how to achieve results by other means. well this whole thread is certainly the raw material for an article (or D blog post) on D operator overloads. Just, someone has to compile the informations and write the said article.
Re: Program crash: GC destroys an object unexpectedly
On Monday, 13 September 2021 at 17:54:43 UTC, eugene wrote: On Monday, 13 September 2021 at 17:40:41 UTC, user1234 wrote: The problems seems to lies in `newSignal()` which "would" not allocate using the GC. final Signal newSignal(int signum) { Signal sg = new Signal(signum); sg.owner = this; sg.number = sg_number++; sg.register(); return sg; } full src is here http://zed.karelia.ru/0/e/edsm-in-d-2021-09-10.tar.gz thx, so the problem is not what I suspected to be (mixed gc-managed and manually managed memory). sorrry...
Re: Program crash: GC destroys an object unexpectedly
On Monday, 13 September 2021 at 17:18:30 UTC, eugene wrote: [...] At first glance and given the fact that some code necessary to diagnose the problem accurately is missing: `new Stopper` allocates using the GC. it's then a "GC range", it's content will be scanned and handled by the GC, including `sg0` and `sg1`. So far everything is simple. The problems seems to lies in `newSignal()` which "would" not allocate using the GC. So when the GC reaches `sg0` and `sg1` values, indirectly when scanning a `Stopper` instance, it thinks that these they are unused and, consequently, free them. If you dont want them to be managed by the GC remove them from the GC, using `removeRange()`.
Re: Program crash: GC destroys an object unexpectedly
On Monday, 13 September 2021 at 17:40:41 UTC, user1234 wrote: On Monday, 13 September 2021 at 17:18:30 UTC, eugene wrote: [...] At first glance and given the fact that some code necessary to diagnose the problem accurately is missing: `new Stopper` allocates using the GC. it's then a "GC range", it's content will be scanned and handled by the GC, including `sg0` and `sg1`. So far everything is simple. The problems seems to lies in `newSignal()` which "would" not allocate using the GC. So when the GC reaches `sg0` and `sg1` values, indirectly when scanning a `Stopper` instance, it thinks that these they are unused and, consequently, free them. If you dont want them to be managed by the GC remove them from the GC, using `removeRange()`. of sorry, or maybe the opposite, so addRange...
Re: Which operators cannot be overloaded and why not?
On Monday, 13 September 2021 at 14:59:38 UTC, Paul Backus wrote: On Monday, 13 September 2021 at 14:42:42 UTC, jfondren wrote: On Monday, 13 September 2021 at 14:33:03 UTC, user1234 wrote: - condition al expression ` cond ? exp : exp ` And many other boolean operators, unary !, binary && and || https://dlang.org/spec/operatoroverloading.html lists all the overloadable operators, and https://dlang.org/spec/expression.html has all the operators, so "which operators" is a matter of close comparison. "why not" is much harder to answer. I think the intent is for the boolean operators to be handled via `opCast!bool`. I didn't see it was already suggested and answered the same... but yet that's exactly the case.
Re: Which operators cannot be overloaded and why not?
On Monday, 13 September 2021 at 15:29:05 UTC, user1234 wrote: [...] so this is a bit like the postincr case. i.e "prevent the semantics to be hijacked".
Re: Which operators cannot be overloaded and why not?
On Monday, 13 September 2021 at 14:42:42 UTC, jfondren wrote: On Monday, 13 September 2021 at 14:33:03 UTC, user1234 wrote: - condition al expression ` cond ? exp : exp ` And many other boolean operators, unary !, binary && and || They are all indirectly supported if `opCast` is overloaded: ```d unittest { struct S { bool opCast(T = bool)(){return true;} } S s; assert(s && s); } ``` so this is a bit like the postincr case.
Re: Which operators cannot be overloaded and why not?
On Monday, 13 September 2021 at 14:33:03 UTC, user1234 wrote: what else ? when you have ```d alias AA1 = int[int]; alias AA2 = AA1[int]; ``` then you can write ```d AA2 aa; aa[0] = [0 : 0]; aa[0][0] = 0; ``` The `[0][0]` cannot be expressed using operator overloads (and a custom map type that implements opIndexAssign).But this case is rather due to the fact that druntime seems to do something a bit unusal here (according to an old discussion that happend once on irc).
Re: Which operators cannot be overloaded and why not?
On Monday, 13 September 2021 at 14:12:36 UTC, NonNull wrote: Which operators cannot be overloaded and why not? Let's start the list. - `new` and `delete` Because operators are overloaded in aggregates new was supported but not anymore, the idea is that a an aggregate should not be tied a specific allocator. - post incr/decr See [https://dlang.org/spec/operatoroverloading.html#postincrement_postdecrement_operators](explantations). This is an arbitrary limitation imho but the current way enfore that the side effect is not apllied to the expression result. - condition al expression ` cond ? exp : exp ` No idea why it is not supported... nobody has never complained tho ;) - `typeid` Same... the result of typeid has to be a TypeInfoClass, so there's not much to do... exactness is expected - `is` (identity) could be but I suppose that this stuff needs to be correct to keep code consistent what else ?
Re: Need for std.meta.isSame over __traits(isSame)
On Wednesday, 1 September 2021 at 23:04:18 UTC, Per Nordlöw wrote: On Wednesday, 1 September 2021 at 22:51:40 UTC, Per Nordlöw wrote: Can somebody explain the need for Ok, `__traits(isSame)` always returns false for values. This is very unfortunate as `std.traits.isSame` is one of the most used template instances in typical std.meta-programming and has a noticeable impact on time and space complexity now that AliasAssign-enabled versions of std.meta members have removed the need for other costly recursive template patterns. I suggest we add a new builtin trait that exactly mimics std.traits.isSame or inline the calls to `isSame` in `std.traits.meta`. This is gonna significantly speed up functions in std.meta, for instance `staticIndexOf`, `EraseAll`, `GenericReplace`, `ReplaceAll`, `Pack`. I suggest to change the template signature instead: ```d template isSame(Args...) if (Args.length == 2) { enum isSame = __traits(isSame, Args[0], Args[1]); } ``` The problem is not `__traits(isSame)`, it's more the TemplateAliasParameter, as observed previously.
Re: Need for std.meta.isSame over __traits(isSame)
On Wednesday, 1 September 2021 at 22:51:40 UTC, Per Nordlöw wrote: Can somebody explain the need for ```d private template isSame(alias a, alias b) { static if (!is(typeof( && )) // at least one is an rvalue && __traits(compiles, { enum isSame = a == b; })) // c-t comparable { enum isSame = a == b; } else { enum isSame = __traits(isSame, a, b); } } ``` when there is already ```d __traits(isSame, a, b) ``` ? Are there any cases where ```d __traits(isSame, a, b) ``` doesn't have the same value as ```d a == b ``` provided the static if expression above is true. the traits does not work on literals passed by _AliasTemplateParameter_. ```d enum isSame1(alias a, alias b) = a == b; enum isSame2(alias a, alias b) = __traits(isSame, a, b); pragma(msg, isSame1!(0, 0)); // true pragma(msg, isSame2!(0, 0)); // false ``` This looks a bit like a bug, because `__traits(isSame, 0, 0)` yields `true`
Re: Singleton Object, calling member functions using UFCS (an "ugly?" example) ... better way?
On Wednesday, 1 September 2021 at 22:01:12 UTC, user1234 wrote: On Wednesday, 1 September 2021 at 20:59:15 UTC, james.p.leblanc wrote: [...] The question is if there is a way to enable UFCS without such wrapper sorry my attention got stuck on the singleton. So my suggestion is rather to only enable the ufcs style. This highlights the fact that the class is useless, you can use a simple getter that initializes a hidden global: ```d module gnuplot_mod; import std.stdio; import std.process; import std.algorithm : each; import std.range : enumerate; ProcessPipes gnuplot () { __gshared ProcessPipes pipe; return pipe.pid ? pipe : (pipe = pipeProcess("/usr/local/bin/gnuplot")); } static void cmd(string txt) { with (gnuplot()) { stdin.writeln(txt); stdin.flush(); } } static void plot(double[] x, string txt = "ls 21 lw 2"){ with (gnuplot()) { stdin.writeln("plot '-' u 1:2 with lines ", txt); enumerate(x).each!((i,v) => stdin.writefln!"%s %f"(i, v))(); sorry there was a format mistake not detected at compile time. ```diff - enumerate(x).each!((i,v) => stdin.writefln!"%s %f"(i, v))(); + enumerate(x).each!(a => stdin.writefln!"%s %f"(a.index, a.value))(); ``` stdin.writeln("e"); stdin.flush(); } } void main() { double[] x = [1.1, 0.2, 3.1, 2.2, 3.1, 0.6]; double[] y = [-1.1, 0.2, -3.1, 2.2, 3.1, -0.6]; y.plot("ls 41 lw 8"); cmd("pause 2"); } ```
Re: Singleton Object, calling member functions using UFCS (an "ugly?" example) ... better way?
On Wednesday, 1 September 2021 at 20:59:15 UTC, james.p.leblanc wrote: [...] The question is if there is a way to enable UFCS without such wrapper sorry my attention got stuck on the singleton. So my suggestion is rather to only enable the ufcs style. This highlights the fact that the class is useless, you can use a simple getter that initializes a hidden global: ```d module gnuplot_mod; import std.stdio; import std.process; import std.algorithm : each; import std.range : enumerate; ProcessPipes gnuplot () { __gshared ProcessPipes pipe; return pipe.pid ? pipe : (pipe = pipeProcess("/usr/local/bin/gnuplot")); } static void cmd(string txt) { with (gnuplot()) { stdin.writeln(txt); stdin.flush(); } } static void plot(double[] x, string txt = "ls 21 lw 2"){ with (gnuplot()) { stdin.writeln("plot '-' u 1:2 with lines ", txt); enumerate(x).each!((i,v) => stdin.writefln!"%s %f"(i, v))(); stdin.writeln("e"); stdin.flush(); } } void main() { double[] x = [1.1, 0.2, 3.1, 2.2, 3.1, 0.6]; double[] y = [-1.1, 0.2, -3.1, 2.2, 3.1, -0.6]; y.plot("ls 41 lw 8"); cmd("pause 2"); } ```
Re: Singleton Object, calling member functions using UFCS (an "ugly?" example) ... better way?
On Wednesday, 1 September 2021 at 16:02:47 UTC, james.p.leblanc wrote: Dear D-ers, For simple plotting using a gnuplot process, I have created a singleton object (a stripped down minimal working example is below.) [...] **However, those wrapper functions in the gnuplot_mod module looks a bit silly.** [...] Any suggestions on a better way are greatly appreciated. Best Regards, James hello, I'd suggest this: ```d shared static this() { get(); // cache instance before main(){} // to get rid of the synchronized() stmt } static Gnuplot get() { __gshared Gnuplot instance; return instance ? instance : (instance = new Gnuplot()); } ```
Re: DMD compiler - warning of unused variables
On Monday, 16 August 2021 at 14:14:27 UTC, DLearner wrote: Is there a compiler option that would warn that variable 'j' is defined but not used? Best regards No in DMD but you can use [D-Scanner](https://code.dlang.org/packages/dscanner) for that. The check works reasonably as long as the variables are not introduced by `mixin()` or metaprog.
Re: Create alias of same name in inner scope, bug or feature?
On Saturday, 14 August 2021 at 04:09:34 UTC, Tejas wrote: [...] Oh right, the ```.``` operator will reference variable in the _module_ scope, not just the _immediate outer scope_, you can use the module name to disambiguate as well. To extend Mike answer, the general rule is that if you can distinguish two names there's no shadowing.
Re: How to extend the string class to return this inside the square bracket?
On Friday, 13 August 2021 at 23:33:05 UTC, Paul Backus wrote: On Friday, 13 August 2021 at 23:23:55 UTC, Marcone wrote: writeln("Hello World!"[x.indexOf("e")..x.indexOf("r")]); indexOf()is just a simple example, not the goal. I want handle literal inside [] like it bellow, but in literal: string x = "Hello World!"; writeln(x[x.indexOf("e")..x.indexOf("r")]); You can use the `pipe` function to bind an arbitrary expression to a variable: ```d import std.functional: pipe; import std.algorithm: countUntil; import std.stdio: writeln; "Hello world!" .pipe!(s => s[s.countUntil('e') .. s.countUntil('r')]) .writeln; ``` nice, that's the best alternative.
Re: How to extend the string class to return this inside the square bracket?
On Friday, 13 August 2021 at 21:05:22 UTC, Marcone wrote: How to extend the string class to return this inside the square bracket the same way opDollar $ returns the length of the string? Thank you. import std; void main(){ writeln("Hello World!"[0..this.indexOf("o")]); } this does not exist (and see few reason for) but algo + ufcs allows this easily, e.g ``` "Hello World!".findSplit("o")[0].writeln; ``` bonus: both can throw bound error
Re: Debugging linker errors
On Sunday, 8 August 2021 at 11:58:42 UTC, Bogdan wrote: Hi, I tried to update my server from dmd v2.096.1 to v2.097 and I started getting this linker error: ``` Linking... /usr/bin/ld: .dub/build/executable-ssl11-debug-linux.posix-x86_64-dmd_v2.097.2-beta.1-7651E13F70724FF6B1F8D8B61B1AEABD/gis-collective-api.o: in function `_D3std6traits__T6fqnSymS5crateZ11adjustIdentFAyaZQe': /usr/include/dmd/phobos/std/traits.d:737: undefined reference to `_D3std9algorithm9searching__T8skipOverZ__TQnTAyaTQeZQxFNaNfKQpQrZb' /usr/bin/ld: /usr/include/dmd/phobos/std/traits.d:737: undefined reference to `_D3std9algorithm9searching__T8skipOverZ__TQnTAyaTQeZQxFNaNfKQpQrZb' collect2: error: ld returned 1 exit status Error: linker exited with status 1 /usr/bin/dmd failed with exit code 1. ``` What's the best aproach on debugging linker errors with DMD on linux? Best, Bogdan I'd try the following options - `--force` dub to rebuild everything. - `-allinst` in the dflags. - `-verbose` output can show interesting details sometimes. - the different linking mode proposed by dub. if one of te following fixes the issue then maybe that digger can help to detect a regression.
Re: Is returning void functions inside void functions a feature or an artifact?
On Monday, 2 August 2021 at 14:31:45 UTC, Rekel wrote: I recently found one can return function calls to void functions, though I don't remember any documentation mentioning this even though it doesn't seem trivial. [...] If this is intended, where could I find this in the docs? I haven't been able to find previous mentions on this, neither on the forum. You got the answer in another reply but here is a bit of more fun: ```d void main() { return cast(void) 1; } ``` it's all about the type system and conversions
Re: Registering-unregistering threads
On Friday, 30 July 2021 at 23:48:41 UTC, solidstate1991 wrote: I'm doing some audio-related work, and one thing I need is to unregister from (and maybe later temporarily re-register to) the GC, since it would cause some issues, GC + audio is only a problem if its pauses (e.g in the audio thread) are longer than the time required to create a buffer (as obviously computer audio is **not real-time**). Let's say you have 3 msecs GC pause, 12 msecs to create a buffer, if the driver latency is of 22 msecs then the rendering will not be affected, e.g when the driver reclaims a buffer it is ready and no perceptible crackling occurs. and it would be nice if I still could use the GC during disk operations, etc. Info on it is quite scarce and a bit confusing. If I unregister from the RT, will that mean it'll be GC independent, or will have other consequences too? Mixin C heap memory and GC memory is a known source of issues because of GC roots. A simpler solution is to continue using the GC memory (e.g `new`) but control manually when it runs using `GC.enable`, `GC.disable` and `GC.collect`, `GC.minimize`.
Re: Why are class methods not allowed to call cons/destructors?
On Saturday, 31 July 2021 at 13:12:21 UTC, Tejas wrote: ```d class A{ ~this(){} destructA(){ ~this() } } class B:A{ ~this(){} destructB(){ ~this(); ~super(); } } ``` This could allow ```@nogc``` crowd to run destructors without calling ```destroy```. Yes, derived to base conversion is still a thing and someone who invokes the destructor just by looking at the parameter's type could get fooled, atleast we will have a way to destroy class instances without the gc. Are there other problems? I'm genuinely curious. I guess we can still just define normal methods and invoke them, but atleast this will allow us to maintain consistency with the gc crowd. `destroy` is not the problem, see https://forum.dlang.org/post/jsrjgmeblfukwhqbw...@forum.dlang.org the problem is **what is called in `destroy()`** see https://forum.dlang.org/post/rdcadsqsmszqg...@forum.dlang.org for a very simple solution.
Re: Why does Unconst exist?
On Wednesday, 28 July 2021 at 05:38:44 UTC, Tejas wrote: When I initially saw it, I was hopeful that it would allow me to bypass some of the restrictions of ```const``` , but it literally just takes a type and strips the ```const``` from it, you can't pass a variable to it in order to get rid of ```const``` . What use does it serve then? To manipulate types in template metaprogramming. To remove `const` from a variable, `cast() stuff` is shorter than `cast(Unconst!(typeof(stuff))) stuff`, but it also removes `shared` and `immutable.
Re: Destructors can't be @nogc?
On Friday, 23 July 2021 at 20:24:02 UTC, Jim wrote: Hello, I've been playing with D and trying to understand how to work with @nogc. I must be doing something wrong, because even though I tagged the destructor for my class `@nogc`, I'm getting the following error: `.\min.d(27): Error: "@nogc" function "D main" cannot call non-@nogc function "object.destroy!(true, TestClass).destroy` [...] What is the problem here? Should I not call `destroy`? If so, `destroy()` uses the runtime types informations to detect the most derived destructor (as you might cast from `TestClass` to least specialized, i.e `Object`). The type infos for classes stores the destructor in form of a function pointer that has not `@nogc` as part of its attributes. what should I call instead? get rid of `destroy()` and instead use your own allocator, virtual constructor (instead of `this(){}`) and virtual destructor (instead of `~this(){}`) in a base class. e.g ```d class Base { static auto make(T : Base, Args...)(Args args) { auto size = __traits(classInstanceSize, T); auto memory = malloc(size)[0..size]; T t = emplace!(T)(memory); t.construct(args); // call the most derived return t; } void construct() @nogc { printf("Base constructor called\n"); } void destruct() @nogc { printf("Base destructor called\n"); free(cast(void*) this); } } class Derived : Base { override void construct() @nogc { super.construct(); // construct from base to most derived printf("Derived constructor called\n"); } override void destruct() @nogc { printf("Derived destructor called\n"); super.destruct(); // destruct from derived to base // finishing with the deallocation } } void main(string[] args) @nogc { Base b = Base.make!(Derived); b.destruct(); } ``` things get called correctly Base constructor called Derived constructor called Derived destructor called Base destructor called That bypasses the runtime mechanism for classes construction and destruction. But `new` and `destroy` must not be called anymore, you must get stick with your own system.
Re: Destructors can't be @nogc?
On Sunday, 25 July 2021 at 01:17:06 UTC, user1234 wrote: That bypasses the runtime mechanism for classes construction and destruction. But `new` and `destroy` must not be called anymore, you must get stick with your own system. and of course `cast(Object)` should be prohibited (maybe `opCast` overload can enforce that).
Re: Generate docs for generated code?
On Friday, 23 July 2021 at 10:04:55 UTC, wjoe wrote: Is there a way for the compiler to consider doc comments in auto generated, mixed in code? E.g. ```D string fooImpl = q{ /// Bar does fancy things. const void bar() { /*do something fancy*/ } }; /// This is Foo struct Foo(A, B, C) { mixin(fooImpl); } ``` So that the documentation for ```struct Foo``` has that of the member ```bar()``` ? unfortunately no and this is considered as a [bug](https://issues.dlang.org/show_bug.cgi?id=2420)
Re: How to select the regex that matches the first token of a string?
On Saturday, 3 July 2021 at 09:05:28 UTC, vnr wrote: Hello, I am trying to make a small generic lexer that bases its token analysis on regular expressions. The principle I have in mind is to define a token type table with its corresponding regular expression, here is the code I currently have: [...] storing the regex in a token is an antipattern.
Re: dlang vs crystal-language
On Saturday, 1 May 2021 at 13:04:15 UTC, sighoya wrote: On Wednesday, 28 April 2021 at 22:41:03 UTC, Alain De Vos wrote: What are the strengths and weaknesses comparing the two languages ? I can name a strength of dlang is the working binding to tk and gtk. Just to say, Crystal is a neat language, feels like a static ruby. Strengths: - Poweful type inference - lightweight julian/ruby like syntax - nice lightweight macros, don't know if they were a good fit for D - nice yield builtins - feels like a lightweight Java - nice high level feeling and is GCed Weaknesses: - as I said, it is hard to understand when type inference is used completely everywhere, said that this is crystals killer feature - slow compilation time just because of the "type inferred everywhere" design I seriously wonder if this is a criterion. For example Gitlab which is known to get updated each month, still uses Ruby in their backend. So their clients use scripts that could be 2x to 20x faster if made in Crystal. - the OOP system lacks specific features from other OOP systems - hasn't the same support for low level programming as in D or Nim - is relative unknown, although I don't know why.
Re: Since dmd 2.096.0: import `x.t` is used as a type
On Friday, 30 April 2021 at 17:58:43 UTC, kdevel wrote: dmd since 2.096.0 with ``t.d`` ```t.d module t; class t { } ``` and ``x.d`` ```x.d module x; import t; void main () { t x = new t; } ``` reports $ dmd -i x.d x.d(6): Error: import `x.t` is used as a type x.d(6): Error: import `x.t` is used as a type Could not find this Change in https://dlang.org/changelog/2.096.0.html. Has this been "fixed" with some other issue? Workaround: ```x.d ... import t : t; ... ``` Likely a side effect of https://github.com/dlang/dmd/pull/12178 but according to me the new behavior is correct.
Re: Deriving a D-class from a CPP-class
On Thursday, 29 April 2021 at 06:38:53 UTC, evilrat wrote: On Wednesday, 28 April 2021 at 19:46:00 UTC, Alain De Vos wrote: It is rather clear what I want to achieve but virtual functions give me headache because dlang does not now the word virtual. It's virtual by default. The opposite is `final`. by default, excepted if protection is private or package.
Re: Static array initialisation
On Thursday, 1 April 2021 at 09:30:28 UTC, DLearner wrote: On Wednesday, 31 March 2021 at 23:21:59 UTC, russhy wrote: On Wednesday, 31 March 2021 at 17:54:38 UTC, DLearner wrote: [...] Can you show the print function? Maybe the problem lies there? Using rdmd, I believe the code below demonstrates the situation. import std.stdio; void main() { immutable uint MemSize=100; // Memory size in bytes. uint counter; uint idx; ubyte* WkPtr; ubyte WkUbyte; // Memory Pool ubyte[MemSize] MemPool = 8; // Initialised to 8 for debugging. WkPtr = [0]; counter = 1; while (counter <= 102) { idx = counter - 1; WkUbyte = *(WkPtr + idx); writeln("idx = ", idx, "WkUbyte = ", WkUbyte); counter = counter + 1; } } memset would fill a whole page even if the specified size is in the middle of a page. Try with 64, 4096 for example, instead of 100.
Re: rdmd and D equivalent for PYTHONPATH?
On Wednesday, 17 March 2021 at 07:13:31 UTC, Chris Piker wrote: On Wednesday, 17 March 2021 at 06:07:01 UTC, user1234 wrote: [...] Very handy example. Unfortunately it means that paths are embedded in scripts, which is usually a bad idea. [...] You can use a local registry too. That should work but ten the dep version must be set to "*". See https://dub.pm/commandline.html#add-local
Re: rdmd and D equivalent for PYTHONPATH?
On Wednesday, 17 March 2021 at 04:34:07 UTC, Chris Piker wrote: On Wednesday, 17 March 2021 at 03:43:22 UTC, Chris Piker wrote: Note: I'm aware of dub. This isn't a question about dub. I'm making scripts for local use, not redistributable binaries, so I would like to "install" mir-algorithm and similar libraries for my rdmd scripts to use. Sorry to reply to myself, but I found something that will run the scripts, though it still doesn't make use of local libraries. #!/usr/bin/env dub /+ dub.sdl: dependency "mir-algorithm" version="~>1.0" +/ import mir.ndslice ... Since dub seems to work a bit better as the "interpreter" then rdmd (assuming you're connected to the Internet) You can use local a specific local version too, for example the git repository #!/usr/bin/env dub /+ dub.sdl: dependency "mir-algorithm" path="/home/x/repositories/mir/mir-algorithm" +/ In addition with --nodeps, no internet is required.
Re: D's Continous Changing
On Thursday, 4 March 2021 at 09:21:12 UTC, Siemargl wrote: On Thursday, 4 March 2021 at 06:43:57 UTC, user1234 wrote: otherwise another solution is to check every two monthes the sanity of your projects. E.g a montly cronjob on a CI service and that uses latest DMD Docker image. If it fails you got an email... It certainly cooler to take 5 mins every two monthes than 7 hours 4 years. Nice idea. Try do it with all hundreds of used in your projects libraries. isObject, isArray, etc ;) ?
Re: D's Continous Changing
On Thursday, 4 March 2021 at 05:44:53 UTC, harakim wrote: For the record, I was able to resolve all of my issues in about 7 hours. That included upgrading from DerelictSDL to bindbc and converting to use dub instead of make. I hope my above post does not lead people to believe that I don't like D, because I otherwise wouldn't have lost track of time until midnight working on this project! I also should mention that this project was probably last touched in 2017. I thought I pulled it out a year ago, but that was a different project. otherwise another solution is to check every two monthes the sanity of your projects. E.g a montly cronjob on a CI service and that uses latest DMD Docker image. If it fails you got an email... It certainly cooler to take 5 mins every two monthes than 7 hours 4 years.
Re: DUB is not working correctly
On Thursday, 25 February 2021 at 17:34:29 UTC, Maxim wrote: In my opinion, that happens because of DUB can't accept my changes to the file. But how to make the manager admit it? I apologize to everyone who understood me wrong. If you use an ide to edit the DUB receipt maybe it's possible that you forgot to save the project before retriggering a rebuild. If so then the file used by DUB is still in its previous state.
Re: Ugly c++ syntax
On Friday, 5 February 2021 at 21:10:21 UTC, Rumbu wrote: Can some C++ guru translate in D the template below? I gave up after reading a lot, but I didn't manage to understand the meaning "&& ..." template static uint8_t composite_index_size(Tables const&... tables) { return (composite_index_size(tables.size(), impl::bits_needed(sizeof...(tables))) && ...) ? 2 : 4; } Thanks. modern cpp looks like 10 lines of decl for 1 of actual code.
Re: How to debug D on Linux
On Wednesday, 13 January 2021 at 13:47:55 UTC, Roguish wrote: On Wednesday, 13 January 2021 at 13:30:48 UTC, Roguish wrote: Anything else I need to know when debugging on Linux, without an IDE? One specific question I have is: what's the difference between -g and -debug and -d-debug? Also, what does it mean to "always emit a stackframe" (compiler option -gs) ? -g : generate dwarf info, the debug info, the most important -debug : compiles the debug statements, e.g debug logging. not so important, this is a conditional compilation feature. -gs: always emit a prelude/prologue. but dmd pretty much always do that even when not required (sigh). You really mostly only requires -g. Then you have to learn gdb. A few basis to get started, a session for a segfault is often like $ gdb ./myapp $ run and when it crashes, note the source position, additionally $ bt $ p somevar $ p some.more.complex.expression may already give interesting infos. If not, during a second session you will rather put breakpoints to see what happens before the access violation and step from that breakpoint to the code that accesses unowned memory. $ gdb ./myapp $ break .d $ run and then step by step, each time it pauses you inspect the interesting stuff. Note that I may be wrong on the syntax of the commands as I always use an IDE GUI.
Re: Request assistance initializing struct instance at global scope
On Monday, 7 December 2020 at 05:28:41 UTC, user1234 wrote: On Monday, 7 December 2020 at 04:13:16 UTC, Andrew Edwards wrote: Given: === extern(C): char*[] hldr; enum I = (1<<0); struct S { char* ft; char** fm; int f; } void main(){} === How do I initialize an instance of S at global scope? You cant. At the global scope the initializers must be runnable at compile time, i.e using CTFE. I've tried to simplify what would be required: --- extern(C): char*[] hldr; enum I = (1<<0); struct S { char* ft; char** fm; int f; } void main(){} enum char[8] FirstLevel = ['0']; enum DoubleLevel = [0]; // here S[] s = [ S( FirstLevel.ptr, DoubleLevel, // error is here actually, interesting 0), ]; --- D is not able of that : /tmp/temp_7F835402B0F0.d:9:28: Error: cannot use non-constant CTFE pointer in an initializer `&['0', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff'][0]` sorry my example was bad, better one --- extern(C): char*[] hldr; enum I = (1<<0); struct S { char* ft; char** fm; int f; } void main(){} enum char[8] Stuff = ['0']; enum FirstLevel = Stuff.ptr; // so char* OK S[] s = [ S( FirstLevel, // char* OK , // error here char** NG at CTFE 0), ]; ---
Re: Request assistance initializing struct instance at global scope
On Monday, 7 December 2020 at 04:13:16 UTC, Andrew Edwards wrote: Given: === extern(C): char*[] hldr; enum I = (1<<0); struct S { char* ft; char** fm; int f; } void main(){} === How do I initialize an instance of S at global scope? You cant. At the global scope the initializers must be runnable at compile time, i.e using CTFE. I've tried to simplify what would be required: --- extern(C): char*[] hldr; enum I = (1<<0); struct S { char* ft; char** fm; int f; } void main(){} enum char[8] FirstLevel = ['0']; enum DoubleLevel = [0]; // here S[] s = [ S( FirstLevel.ptr, DoubleLevel, // error is here actually, interesting 0), ]; --- D is not able of that : /tmp/temp_7F835402B0F0.d:9:28: Error: cannot use non-constant CTFE pointer in an initializer `&['0', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff'][0]`
Re: ParameterIdentifierTuple returns empty strings
On Wednesday, 2 December 2020 at 11:46:26 UTC, Andre Pany wrote: Hi, I need to retrieve the parameter identifier but only empty strings are returned: tuple("", "") ``` d alias fpt = extern(C) nothrow void function(int a, int b); void main() { import std.traits : ParameterIdentifierTuple; pragma(msg, ParameterIdentifierTuple!(fpt)); } ``` Where is here the error? Kind regards André If you look at the template [1] implementation, function pointers are rejected, apparently because of a `__parameters` limitation. There something to report. Bad documentation at least. [1]: https://github.com/dlang/phobos/blob/2c0660141748a13637ff473cbb7b0d52eb1c44db/std/traits.d#L1400