Re: need help to check symbol is static variable or not
On Monday, 1 July 2024 at 07:32:30 UTC, Dakota wrote: this code give error: ```d static if( !__traits(compiles, mixin("enum v = V;")) ) { enum v = V; } ``` __traits(compiles, ...) can't check if a declaration is valid directly. You have to wrap it in a function literal expression: ```d enum isStatic(alias V) = __traits(compiles, { enum v = V; }); extern const float NotWorkVar; const float Works = 2; pragma(msg, isStatic!NotWorkVar); // false pragma(msg, isStatic!Works); // true ```
Re: Default struct constructors if a struct member is a union
On Saturday, 29 June 2024 at 23:33:41 UTC, solidstate1991 wrote: S foo0 = S(TypeEnum.Integer32, S(20)); //Ugly, but works S foo1 = S(TypeEnum.Integer64, S(20L)); //Error: cannot Did you mean `U(20)`? The 20 applies to the first field of the union, i32. `U(20L)` also works and (I think) it does the same because of VRP. My question is can I initialize structs like these in one line without relying on a second line? My usecase scenario doesn't really allow constructors for the struct, since it's a binding to an external library via C API. You can use a field initializer: ```d enum TypeEnum { Integer32, Integer64 } union U { int i32; long i64; float f32; double f64; } struct S { TypeEnum type; U data; } S foo0 = S(TypeEnum.Integer32, U(20)); // init i32 S foo1 = S(TypeEnum.Integer64, U(f32: 0.5F)); // struct initializer syntax S foo2 = {TypeEnum.Integer32, {20}}; S foo3 = {TypeEnum.Integer64, {f32: 0.5F}}; // init f32 void main() { assert(foo0.data.i32 == 20); assert(foo3.data.f32 == 0.5F); } ```
Re: Why `foo.x.saa.aa` and `foo.y.saa.aa` is the same? `shared_AA.saa` should still be instance variable, not class variable, right?
On Tuesday, 25 June 2024 at 02:16:25 UTC, mw wrote: Why `foo.x.saa.aa` and `foo.y.saa.aa` is the same? (and of course print out the same contents). `shared_AA.saa` should still be instance variable, not class variable, right? `saa` is an instance variable, but both `foo.x.saa` and `foo.y.saa` are initialized to the same instance of `shared_AA_class`. I think in the next edition of D we can forbid tail mutable initializers. BTW there's also another issue that the initializer is not TLS - that could probably be fixed (also in an edition) to use TLS. https://forum.dlang.org/post/sexmkjnbtxvsvodca...@forum.dlang.org
Re: DIP1046, "ref For Variable Declarations", has been Accepted
On Sunday, 23 June 2024 at 21:50:37 UTC, Vladimir Marchevsky wrote: On Sunday, 23 June 2024 at 13:29:21 UTC, Mike Parker wrote: DIP1046, "ref For Variable Declarations", has been accepted: https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1046.md which reduces the complexity of the code, as long-winded global names get a shorthand Does ref add anything compared to using an alias?.. `ref` will bind to lvalue expressions, e.g (from the DIP): ```d ref int dark(ref int x, int i, int* q) { ref m = *q;// m refers to whatever q points to ... } ``` `*q` is an expression, not a symbol. `ref` can bind to e.g. a struct field runtime value, or an lvalue returned from a function. `alias` only allows giving new names for existing compile-time symbols.
Re: How to generate a random number from system clock as seed
On Saturday, 8 June 2024 at 16:09:04 UTC, monkyyy wrote: rng is an optional parameter, `uniform(0,100).writeln;` alone works; the docs not telling you that is really bad They do tell you: urng (optional) random number generator to use; if not specified, defaults to rndGen That overload is used in the 2nd example. https://dlang.org/phobos/std_random.html#.uniform
Re: Unintentional sharing?
On Thursday, 6 June 2024 at 17:49:39 UTC, Andy Valencia wrote: I was using instance initialization which allocated a new object. My intention was this initialization would happen per-instance, but all instances appear to share the same sub-object? That is, f1.b and f2.b appear to point to a single object? Obviously I moved the new into the initializer code, but I hadn't appreciated how initial instance values were calculated once. Interestingly, this makes it similar to how Python calculates default argument values for functions. class Bar { int z = 3; } class Foo { auto b = new Bar(); } void main() { import std.stdio : writeln; auto f1 = new Foo(), f2 = new Foo(); f1.b.z = 0; writeln(f2.b.z); } This is a long standing issue: https://issues.dlang.org/show_bug.cgi?id=2947 I think with the next edition we can disallow (tail) mutable initializers for fields (and TLS globals too).
Re: How to pass in reference a fixed array in parameter
On Wednesday, 5 June 2024 at 09:24:23 UTC, evilrat wrote: for simple cases like this it might work, but 2d array is not even contiguous, A 2D static array is contiguous: https://dlang.org/spec/arrays.html#rectangular-arrays D static arrays, while using the same syntax, are implemented as a fixed rectangular layout in a contiguous block of memory
Re: How to pass in reference a fixed array in parameter
On Wednesday, 5 June 2024 at 10:27:47 UTC, Nick Treleaven wrote: foreach (i, row; maze) slices[i] = row; Sorry that assignment was wrong (edited at last minute). Fixed: ```d import std.stdio; alias s_cell = int; void main() { writeln("Maze generation demo"); s_cell [5][5] maze; int n; foreach (i, row; maze) foreach (j, col; row) maze[i][j] = n++; s_cell[][5] slices; foreach (i, _; maze) slices[i] = maze[i]; print_maze (slices); } void print_maze ( s_cell [][] maze ) { foreach (a; maze) a.writeln(); } ```
Re: How to pass in reference a fixed array in parameter
On Wednesday, 5 June 2024 at 10:27:47 UTC, Nick Treleaven wrote: //~ void print_maze ( s_cell [][] maze... ) I meant to delete that line!
Re: How to pass in reference a fixed array in parameter
On Tuesday, 4 June 2024 at 12:22:23 UTC, Eric P626 wrote: ~~~ void main() { writeln("Maze generation demo"); s_cell [5][5] maze; print_maze (maze); } void print_maze ( s_cell [][] maze ) { } ~~~ This is how to do it without GC allocations (I have used `int` instead for demo purposes): ```d import std.stdio; alias s_cell = int; void main() { writeln("Maze generation demo"); s_cell [5][5] maze = [0, 1, 2, 3, 4]; s_cell[][5] slices; // static array of 5 slices foreach (i, row; maze) slices[i] = row; print_maze (slices); } //~ void print_maze ( s_cell [][] maze... ) void print_maze ( s_cell [][] maze ) { foreach (a; maze) a.writeln(); } ```
Re: How to pass in reference a fixed array in parameter
On Wednesday, 5 June 2024 at 06:22:34 UTC, Eric P626 wrote: Now according to the book, it's possible to assign a slice from a fixed array. This code will compile: ~~~ int[12] monthDays = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]; int[] a_slice = monthDays; ~~~ The element types are both int, so the compiler can slice the static array. As if you had written `a_slice = monthDays[];`. How come the assignment does not work when passing a parameter. I tried the following and it failed: ~~~ s_cell [5][5] maze; The element type is s_cell[5]. s_cell [][] sliced_maze = maze; The element type of sliced_maze is s_cell[], so the element types are incompatible. ~~~ void print_maze ( ref s_cell maze ) void print_maze ( ref s_cell [][] maze ) ~~~ From what I found, arrays passed in parameters are always passed by reference. So the ref keyword seems pointless. You don't need `ref` to be able to read the array length and elements. However, if you want to modify the array length, and have it affect the caller's dynamic array, you need `ref`. --- The only solution left is to use pointers. But even this does not seems to work as in C. I created a function with different pointer signature and they all fails. Normally in C, this would have worked: ~~~ s_cell [5][5] maze; create_maze(); Pass `[0][0]` instead. ~~~ Error: function `mprmaze.create_maze(s_cell[][]* maze)` is not callable using argument types `(s_cell[5][5]*)` cannot pass argument `& maze` of type `s_cell[5][5]*` to parameter `s_cell[][]* maze` ~~~ s_cell[5][5] cannot implicitly convert to s_cell[][]. Now I think it expect a 2D array of pointers instead of a pointer on a 2D array. It's also not clear if there is a difference between those 2 notations: ~~~ maze.ptr ~~~ is a pointer to s_cell[5][5]. maze.ptr is a pointer to s_cell[5]. `.ptr` means a pointer to the first element of the array.
Re: bool passed by ref, safe or not ?
On Wednesday, 5 June 2024 at 09:09:40 UTC, Kagamin wrote: On Wednesday, 5 June 2024 at 01:18:06 UTC, Paul Backus wrote: The only safe values for a `bool` are 0 (false) and 1 (true). AFAIK that was fixed and now full 8-bit range is safe. `cast(bool) someByte` is fine - that doesn't reinterpret the bit representation. The problem is certain values such as `0x2` for the byte representation can cause the boolean to be both true and false: https://issues.dlang.org/show_bug.cgi?id=20148#c3 Void initialization of bool and bool union fields are now deprecated in @safe functions as of 2.109. There is a remaining case of casting an array to bool[], which I am working on disallowing in @safe.
Re: Release D 2.109.0
On Sunday, 2 June 2024 at 15:51:04 UTC, Iain Buclaw wrote: Glad to announce D 2.109.0, ♥ to the 44 contributors. This release comes with 15 major changes and 26 fixed Bugzilla issues, including: Thanks! I've written a changelog entry about reinterpreting a byte as bool being unsafe: https://github.com/dlang/dmd/pull/16560 I hope it's OK to update the online changelog with that.
Re: What prevents ImportC from using .h directly?
On Sunday, 12 May 2024 at 21:34:30 UTC, Chris Piker wrote: So, why does ImportC need *.c files exclusively? I'm sure it solves a problem, but I don't know what that problem is. Support for headers has been worked on, but had to be reverted: https://issues.dlang.org/show_bug.cgi?id=23479
Re: "in" operator gives a pointer result from a test against an Associative Array?
On Friday, 10 May 2024 at 15:23:39 UTC, Andy Valencia wrote: On Friday, 10 May 2024 at 03:07:43 UTC, Steven Schveighoffer wrote: Yes, we say that a type has "truthiness" if it can be used in a condition (`while`, `if`, `assert`, etc). So if I may ask for one more small clarification... WRT "truthiness", I've observed that empty arrays are treated as false, non-empty as true. Arrays evaluate to true in boolean conditions if their `.ptr` field is non-null. This is bug-prone and I hope we can remove this in the next edition. However, although I thought a string was basically an immutable array of characters, "" is treated as true, not false? A string literal's `.ptr` field is always non-null, because it is null-terminated.
Re: Why is Phobos `Flag` so overthought ?
On Wednesday, 8 May 2024 at 10:24:07 UTC, Nick Treleaven wrote: Named arguments are optional, so I don't see how they could make Flag redundant. Actually, an external tool could detect when a bool is passed as an argument to a function and warn when not done with a named argument. This would free library APIs from having to use Flag when some users don't care about it. The cost would come in a bit more build system complexity/build time, which might mean a lot less enforcement due to inertia. Though maybe a reasonable trade-off.
Re: Why is Phobos `Flag` so overthought ?
On Thursday, 9 May 2024 at 13:40:56 UTC, cc wrote: It's pointless mandatory verbosity. StopWatch ctor only takes one boolean argument. It doesn't *need* to specify what it relates to. You either already know, or you have to look it up anyway. Flags made sense when you might get the order of multiple bools confused, but if there's only one, *or* if you can use named arguments to avoid ambiguity, So you have justified Flag. there's no point in demanding every parameter be a unique type. It's easy to remember I can pass a bool to a StopWatch to autostart it. But perhaps true means manual start? Remembering can also be used to justify dynamic typing outside of hot loops, I'd rather not rely on remembering with a big team of programmers working on a project. It's less easy to remember that a specific unique type needs to be used, and remembering whether the name/casing of that type was Start, StartNow, StartAuto, Autostart, AutoStart, autostart, autoStart, etc. So just pass it true, and run the compiler. The compiler will tell you what the correct type is. We have a tool in our box already called `true` and that solves the problem. If we had to type out the full name of every argument passed to every function ever written we may as well just adopt ObjC Cocoa style and call it StopWatchWithAutoStartBool(). Strawman.
Re: Why is Phobos `Flag` so overthought ?
On Wednesday, 8 May 2024 at 04:27:13 UTC, cc wrote: It doesn't allow a simple boolean to be used as an argument, or any other Flag as they are different instantiations of a template rather than equivalent aliases. It is however awful, cumbersome, annoying design and needs to be completely phased out now that we have named arguments. Flag enforces that the argument says what it relates to. `true` does not say what it relates to. Named arguments are optional, so I don't see how they could make Flag redundant.
Re: How can I put the current value of a variable into a delegate?
On Monday, 6 May 2024 at 06:29:49 UTC, Liam McGillivray wrote: Here's a line that caused a bug that took me awhile to find: ``` foreach(card; unitCards) card.submitted = delegate() => selectUnit(card.unit); ``` I think you can do: ```d import std.algorithm.iteration : each; unitCards.each!(c => c.submitted = () => selectUnit(c.unit)); ```
Re: How can I put the current value of a variable into a delegate?
On Monday, 6 May 2024 at 06:29:49 UTC, Liam McGillivray wrote: This is because the delegate assignment causes the local `card` variable to remain alive. The delegate that's assigned is linked to this variable itself, not the value at the time that the delegate is assigned. This is https://issues.dlang.org/show_bug.cgi?id=23136. Perhaps it can be fixed in the next edition. Is there a way I can dereference a variable when placing it in a delegate, so that it's current value is used, rather than the variable itself? I think you would need to make an array before the loop, assign to an indexed element and use that in the delegate.
Re: Turning fixed sized array into tuple
On Saturday, 4 May 2024 at 16:58:00 UTC, Dmitry Olshansky wrote: So I have a function: ```d size_t awaitAny(T...)(T args) { ... } ``` And I have: ``d Event*[4] events; `` How do I pass all 4 of events to awaitAny as tuple of arguments? Use `awaitAny(events.tupleof)`? https://dlang.org/spec/arrays.html#array-properties
Re: Phobos function to remove all occurances from dynamic array?
On Wednesday, 1 May 2024 at 01:09:33 UTC, Liam McGillivray wrote: I get compiler errors when using it on other array types. I've tried using it to replace occurrences of a certain object in an array with [] in order to remove all occurrences, but it's not allowed. Can you post a code example?
Re: Challenge Tuples
On Saturday, 27 April 2024 at 15:32:40 UTC, Nick Treleaven wrote: On Saturday, 27 April 2024 at 11:55:58 UTC, Basile B. wrote: foreach const e in u do if echo(is, e, T) do result += e; static if (is(typeof(e) == int)) r += e; Actually I would write that: ```d R r; foreach (e; v) { static if (is(typeof(e) : R)) ```
Re: Challenge Tuples
On Saturday, 27 April 2024 at 11:55:58 UTC, Basile B. wrote: Here's [STYX](https://gitlab.com/styx-lang/styx) solution: function sum[T,U](U u): u32 I think you meant `: T`. { var T result; foreach const e in u do if echo(is, e, T) do result += e; else do result += sum![T](e); return result; } function main(): s32 { assert((1, 2, 3, [1, 3], 5).sum![u32]() == 15); return 0; } Mostly equivalent D: ```d R sum(R = long, T)(T v) { R r; foreach (e; v) { static if (is(typeof(e) == int)) r += e; else r += sum!R(e); } return r; } void main() { import std; assert(tuple(1, 2, 3, [1, 3], 5).sum == 15); } ```
Re: Release D 2.108.0
On Wednesday, 3 April 2024 at 08:39:03 UTC, Ferhat Kurtulmuş wrote: On Tuesday, 2 April 2024 at 21:15:16 UTC, Nick Treleaven wrote: Official docs: https://dlang.org/spec/istring.html Things like: Can it be used in nogc code? etc. Yes, the literal is just a value sequence. Thank you. It looks like run.dlang.org is not using the last dmd version yet. Yes, it's DMD64 D Compiler v2.105.3. I wanted to make the examples runnable in that page but we need a dmd update there. I also noticed the 'dmd-nightly' version is v2.103.0!
Re: Release D 2.108.0
On Tuesday, 2 April 2024 at 19:41:52 UTC, Ferhat Kurtulmuş wrote: Could you please provide a link to the documentation that one should read to know everthing related to string interpolation in dlang. Official docs: https://dlang.org/spec/istring.html Things like: Can it be used in nogc code? etc. Yes, the literal is just a value sequence.
Re: std.traits.ParameterIdentifierTuple problem
On Sunday, 31 March 2024 at 23:05:44 UTC, Carl Sturtivant wrote: Yes, it's not possible to instantiate a function type. But with extern it seems the semantics is fine as a function is not being instantiated. It is merely associating a name with a type: in what sense is this instantiation in any reasonable way? Yes there is no instantiation for extern. But what would be the use of allowing an extern function type instance, when there's no way to instantiate it?
Re: std.traits.ParameterIdentifierTuple problem
On Saturday, 30 March 2024 at 22:37:53 UTC, Carl Sturtivant wrote: I'm inclined to a view that keeps more "it just works" options open. Regard the parameter names as a part of the type (which I am very grateful for them being currently) and just regard part of the definition of "type equality" as being to ignore parameter names when comparing types. With this viewpoint, ParameterIdentifierTuple should be repaired to work with function types just as it works with functions, and the current behavior is a bug. Maybe, but one of its unittests specifically tests that a function pointer has no parameter identifiers: ```d // might be changed in the future? void function(int num, string name) fp; static assert([ParameterIdentifierTuple!fp] == ["", ""]); ``` And changing in the future got quite a bit of push back in that PR link. This is because `fp` is declared using a function pointer type, and the author of the test did not think function pointer types should include identifiers. So it seems logical that ParameterIdentifierTuple should not give identifiers for a function type either. If a function type does include identifiers, then would two function types with the same argument types but different identifiers compare equal using `is`? Incidentally, I tried ```D extern typeof(foo) func; ``` to say that func was an actual function (`extern` so defined elsewhere) whose type was the type of the function `int foo(int num, string name, int);` so I can then use `ParameterIdentifierTuple` on a function, not a type, Nice try! but the compiler said `bug1.d(5): Error: variable ``bug1.func`` cannot be declared to be a function`. Seems unreasonable given the implied semantics. Yes, it's not possible to instantiate a function type.
Re: std.traits.ParameterIdentifierTuple problem
On Saturday, 30 March 2024 at 21:45:34 UTC, Nick Treleaven wrote: On Saturday, 30 March 2024 at 21:25:45 UTC, Carl Sturtivant wrote: OK, so how can I get them? Am I forced to take that string and parse it with CTFE? Lookup the source of ParameterIdentifierTuple and change `FunctionTypeOf!func` to just `func` inside the first `static if`. Sorry, that actually doesn't work.
Re: std.traits.ParameterIdentifierTuple problem
On Saturday, 30 March 2024 at 21:25:45 UTC, Carl Sturtivant wrote: OK, so how can I get them? Am I forced to take that string and parse it with CTFE? Lookup the source of ParameterIdentifierTuple and change `FunctionTypeOf!func` to just `func` inside the first `static if`.
Re: std.traits.ParameterIdentifierTuple problem
On Saturday, 30 March 2024 at 19:23:07 UTC, Carl Sturtivant wrote: $ dmd -c bug1.d int(int num, string name, int) ["", "", ""] bug1.d(9): Error: static assert: "wrong!" ``` Please explain. How do I get the names of the identifiers out of a parameter list at compile time reliably? Although `.stringof` on a function type does include the parameter names, the names are not really part of the type - see: https://github.com/dlang/phobos/pull/3620#issuecomment-288469685 Perhaps `ParameterIdentifierTuple` should give a compile error when given a function type.
Re: Mutate immutable inside shared static constructor
On Saturday, 23 March 2024 at 21:53:43 UTC, Jonathan M Davis wrote: Yes, it's a bug. It's a clear violation of the type system if a non-mutable variable is ever given a value more than once. It should be initialized, and then it should be treated as illegal to ever assign to it - or to do anything else which would mutate it. So, clearly, the logic in static constructors with regards to non-mutable variables is overly simple at the moment. Thanks, filed: https://issues.dlang.org/show_bug.cgi?id=24449
Mutate immutable inside shared static constructor
I've not used static constructors before, but it seems like the following should not be allowed: ```d import std.stdio; immutable int x; @safe shared static this() { x.writeln(); // 0 x = 5; x.writeln(); // 5 x = 6; x++; assert(x == 7); } ``` Should I file a bug to require that `x` is only written to once? That would make it consistent with class constructors: ```d class C { immutable int x; this() { x = 5; x = 6; // error, x initialized multiple times } } ```
Re: Mutability issue
On Saturday, 23 March 2024 at 19:30:29 UTC, Menjanahary R. R. wrote: for (T candidate = T(5); candidate * candidate <= n; candidate += T(6)) { When T is `const int`, the above code declares and initializes a constant variable: ```d const int candidate = const int(5); ``` Then, at the end of each loop iteration, it does: ```d candidate += const int(6); ``` So you are trying to modify a constant. Constants can only be initialized, never assigned. T candidate = (n % T(2) == T(0)) ? n + T(1) : n + T(2); // Start from next Odd for (;; candidate += T(2)) { // Skip even Same here, you declare a constant then try to assign to it at the end of each loop iteration.
Re: DConf Online Livestream Link
On Monday, 18 March 2024 at 11:33:08 UTC, Andrea Fontana wrote: https://github.com/dlang/dconf.org/tree/master/2024/online/slides Thanks!
Re: DConf Online Livestream Link
On Sunday, 10 March 2024 at 16:07:23 UTC, Mike Parker wrote: The countdown is on! I'll kick off the DConf Online Livestream at 14:55 UTC on March 16. You can find it here: https://www.youtube.com/live/8GV_TuYk3lk And if you haven't seen the details yet, take a look here: https://dconf.org/2024/online/index.html See you there! This was great, interesting selection of talks. BTW each link to slides is giving me a 404. Luckily the live stream video is still up to rewind :-)
Re: length's type.
On Friday, 9 February 2024 at 15:19:32 UTC, bachmeier wrote: It's been discussed many, many times. The behavior is not going to change - there won't even be a compiler warning. (You'll have to check with the leadership for their reasons.) Was (part of) the reason because it would disrupt existing code? If that was the blocker then editions are the solution.
Re: Providing implicit conversion of
On Monday, 22 January 2024 at 19:49:19 UTC, Siarhei Siamashka wrote: The two's complement wraparound behavior mandated by the D language spec is a non-technical political decision, intended to make life easier for the DMD compiler developers, but ignoring the needs of the users. Actually it is for compatibility when porting C code to D.
Re: Providing implicit conversion of - memory-safety
On Monday, 22 January 2024 at 19:11:50 UTC, Siarhei Siamashka wrote: On Monday, 22 January 2024 at 16:39:10 UTC, Nick Treleaven wrote: Memory safety issues are a worse class of bug than arithmetic bugs. The latter are reproducible if you feed them the same input. Memory safety bugs are reproducible with the tools like `valgrind`. Not necessarily, valgrind can execute programs too slowly for human input, so anything that relies on timing is difficult to reproduce. It also uses far more memory, it could be too much memory for the system. Whereas arithmetic overflow bugs are a real PITA to debug. Assuming that the incorrect results are even noticed. You're talking about debugging, whereas I'm saying you often don't even have a chance to *notice* memory-safety bugs, because they might not even occur on the development system, only on the production system. And even if you know there's a memory-safety problem, you can't easily narrow down where it is (without language support for memory-safety). With arithmetic problems it's far easier to narrow down which code is causing them. But I'm strongly in favour of catching any bugs at compile-time (and have been since before I discovered D). I just object to anyone trying to downgrade the importance of automated memory-safety checking.
Re: Providing implicit conversion of
On Monday, 22 January 2024 at 01:14:06 UTC, Steven Schveighoffer wrote: The language should not allow unary unsigned anything. This is unlikely to get fixed, just due to the nature of D's philosophy when it comes to C compatibility. It would also break a lot of existing code. I think the bigger issue is implicit conversion from unsigned to signed of the same bit size. In a future edition D could require a larger signed type in order to implicitly convert from unsigned. That would have caught the `long johnstone =` line. Also signed should never convert to unsigned, though I don't think that's happening here.
Re: Permutations of array (slice) ?
On Tuesday, 12 December 2023 at 16:21:46 UTC, Kevin Bailey wrote: On Tuesday, 12 December 2023 at 15:20:23 UTC, Paul Backus wrote: But unfortunately, the code shown now prints 120 lines of: b 120 being suspiciously equal to 5!. The documentation[2] seems to imply that this should be: b abaaa ... This code works for me. (The last 20+ lines are `b`): ```d import std; void main() { char[] as = replicate(['a'], 5); as[0] = 'b'; foreach (perm; as.byChar.permutations) writeln(perm); } ``` Try it on https://run.dlang.io/. Maybe there's some issue on your machine? Also if you use `string as = "abcde";` you can see the permutations better.
Re: D Language Foundation October 2023 Quarterly Meeting Summary
On Wednesday, 6 December 2023 at 16:28:08 UTC, Mike Parker wrote: One way to do that in D is to use `alloca`, but that's an issue because the memory it allocates has to be used in the same function that calls the `alloca`. So you can't, e.g., use `alloca` to alloc memory in a constructor, and that prevents using it in a custom array implementation. You can call `alloca` as a default argument to a function. The memory will be allocated on the caller's stack before calling the function: https://github.com/ntrel/stuff/blob/master/util.d#L113C1-L131C2 I've just tested and it seems it works as a constructor default argument too.
Re: union default initialization values
On Wednesday, 6 December 2023 at 12:38:35 UTC, Nick Treleaven wrote: Correct. So I expected a NaN output for x. However, I wasn't expecting lo == 13835058055282163712 and hi == 32767 where x is of type real, or lo == 9221120237041090560 and hi = 0 where x is of type double. Based on the default initialization rules, I expected both lo and hi to have a value of zero regardless if x is of type double or real. This is what I'm trying to understand, how are these values derived? ulong.sizeof is 8, like double.sizeof. So F.init.lo should have the same bit pattern as F.init.x because they share storage exactly. F.init.hi should be 0 and it is on my system. (*"If the union is larger than the first field, the remaining bits are set to 0"*). I don't know why you don't get zero for that. Oops, you said you did get zero in that case, so all is well. When `x` is `real`, that may overlap with `F.hi` because `real` can be more than 8 bytes.
Re: union default initialization values
On Tuesday, 5 December 2023 at 19:47:38 UTC, confuzzled wrote: On 12/6/23 4:28 AM, Adam D Ruppe wrote: On Tuesday, 5 December 2023 at 19:24:51 UTC, confuzzled wrote: Given the following union union F { double x; struct { ulong lo; ulong hi; } } The default value of this would be `double.init`, since the first member of the union is a `double`, which is a kind of NaN. This is non-zero. Correct. So I expected a NaN output for x. However, I wasn't expecting lo == 13835058055282163712 and hi == 32767 where x is of type real, or lo == 9221120237041090560 and hi = 0 where x is of type double. Based on the default initialization rules, I expected both lo and hi to have a value of zero regardless if x is of type double or real. This is what I'm trying to understand, how are these values derived? ulong.sizeof is 8, like double.sizeof. So F.init.lo should have the same bit pattern as F.init.x because they share storage exactly. F.init.hi should be 0 and it is on my system. (*"If the union is larger than the first field, the remaining bits are set to 0"*). I don't know why you don't get zero for that.
Re: Inversion of conditional compilation statements
On Saturday, 2 December 2023 at 15:03:25 UTC, ryuukk_ wrote: I wish we could use ``version`` as expression, to void the repetition: ```D import std.stdio; enum HasTest = version (Test) ? true : false; Tomek Sowiński wrote this template: ```d enum bool isVersion(string ver) = !is(typeof({ mixin("version(" ~ ver ~ ") static assert(0);"); })); static assert(isVersion!"assert"); static assert(!isVersion!"Broken"); ```
Re: D: Convert/parse uint integer to string. (@nogc)
On Monday, 27 November 2023 at 12:34:30 UTC, Nick Treleaven wrote: On Friday, 24 November 2023 at 09:35:00 UTC, BoQsc wrote: You can use std.conv.toChars: ```d void main() @nogc { int n = 515; import std.conv; char[10] s = 0; auto r = n.toChars(); assert(r.length < s.length); size_t i; foreach (c; r) s[i++] = c; import core.stdc.stdio; puts(s.ptr); } ``` Or, using std.experimental.allocator: ```d void main() @nogc { int n = 515; import std.conv; import std.experimental.allocator; import std.experimental.allocator.mallocator; alias a = Mallocator.instance; auto s = a.makeArray(n.toChars); assert(s == "515"); a.dispose(s); } ```
Re: D: Convert/parse uint integer to string. (@nogc)
On Friday, 24 November 2023 at 09:35:00 UTC, BoQsc wrote: I tried to look into https://dlang.org/phobos/std_conv.html Most of the functions inside `std.conv` seem to be dependant on [Garbage Collection](https://dlang.org/spec/garbage.html). And I couldn't find a straightforward way to produce a `string` value out of `uint` value. How to convert or parse `uint` value to a `string` in `@nogc` way? You can use std.conv.toChars: ```d void main() @nogc { int n = 515; import std.conv; char[10] s = 0; auto r = n.toChars(); assert(r.length < s.length); size_t i; foreach (c; r) s[i++] = c; import core.stdc.stdio; puts(s.ptr); } ```
Re: Struct copy constructor with inout
On Tuesday, 14 November 2023 at 13:58:17 UTC, Paul Backus wrote: On Tuesday, 14 November 2023 at 13:41:32 UTC, Steven Schveighoffer wrote: ``` Error: copy constructor `testinoutctor.S1.this(ref const(S1) s) const` is not callable using argument types `(const(S1))` ``` I'm not sure what this means. There shouldn't be a copy being made here, as the thing is already const. I don't understand this error, and it looks like a bug to me. The error is saying that the copy constructor expects a `const` `this` argument, but you're passing a mutable `this` argument. Thanks for explaining, it's a confusing error. The error when the constructor is changed to be immutable is: ``` Error: `immutable` method `immutable_ctor.S1.this` is not callable using a mutable object ``` (I've made a fix to say constructor instead of method for that.) Now I've made a fix to produce a similar error for const: https://issues.dlang.org/show_bug.cgi?id=24248
Re: dlang.org/spec/function.html#pure-functions example
On Monday, 16 October 2023 at 18:05:04 UTC, Paul wrote: On Thursday, 12 October 2023 at 21:20:44 UTC, Jonathan M Davis wrote: look like? Types can have static members. Basically what it comes down to is that outside of immutable data, pure functions only have access to their arguments and to what they can access via their arguments (be it by getting pointers from those arguments or calling other pure functions on them). - Jonathan M Davis Can I say in the general sense that when the word static is used it means that something is defined/declared at compile time? This link should describe all the uses of `static`: https://dlang.org/spec/attribute.html#static
Re: How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?
On Tuesday, 10 October 2023 at 11:45:25 UTC, Dennis wrote: ```D enum itoa(int i) = i.stringof; static foreach(i; 0 .. 10) { mixin(create_fn!(itoa!i)); } ``` You can also do it using a string mixin: mixin(create_fn!(mixin("`", i, "`"))); I think that's equivalent to `i.stringof` anyway.
Re: dlang.org/spec/function.html#pure-functions example
On Thursday, 12 October 2023 at 19:33:32 UTC, Paul wrote: If **int x** is global mutable state, what does static mutable state look like? In addition to Jonathan's reply, see: https://dlang.org/spec/function.html#local-static-variables
Re: how to assign multiple variables at once by unpacking array?
On Saturday, 7 October 2023 at 17:23:40 UTC, ryuukk_ wrote: there was a DIP for tuple/deconstruction prior to that question, sadly nothing came out of it, I don't think it was formally submitted. and now the language is frozen... The DIP process is temporarily suspended, it may be modified. The priority for (most of) this year is fixing bugs. However language changes do happen, e.g. just this weekend switch can now declare a variable in the condition. Atila is working on a DIP for editions.
Re: C to D: please help translate this weird macro
On Thursday, 21 September 2023 at 16:28:25 UTC, Nick Treleaven wrote: return cast(T*)(cast(void*)(cast(char*)ptr - __traits(getMember, T, member).offsetof))); There's a trailing `)` that needs removing. Also pretty sure it can be simplified to: return cast(T*)(cast(char*)ptr - __traits(getMember, T, member).offsetof);
Re: C to D: please help translate this weird macro
On Thursday, 21 September 2023 at 02:57:07 UTC, Ki Rill wrote: On Thursday, 21 September 2023 at 02:23:32 UTC, Ki Rill wrote: wrote: [...] Translated it to this eventually: ```D auto nk_container_of(P, T)(P ptr, T type, const(char)* member) { return cast(T*)(cast(void*)(cast(char*) (ptr - __traits(getMember, type, member).offsetof))); } ``` The 1st argument of `getMember` can just be T, like the original macro. The 2nd argument needs to be a compile-time string. Also the `char*` cast needs to apply to `ptr` before subtracting the offset AFAICS. So reordering to keep type inference of `ptr`: ```d auto nk_container_of(T, string member, P)(P ptr) { return cast(T*)(cast(void*)(cast(char*)ptr - __traits(getMember, T, member).offsetof))); } ``` (Untested)
Re: container vs standard array
On Tuesday, 19 September 2023 at 19:57:34 UTC, Nick Treleaven wrote: This is because a single array can be passed to a typesafe variadic parameter rather than elements of that array type. And then immutable(char) doesn't convert to string. I think a non-variadic overload could be added to make it work as expected. https://github.com/dlang/phobos/pull/8818
Re: container vs standard array
On Tuesday, 19 September 2023 at 06:35:01 UTC, JG wrote: On Tuesday, 19 September 2023 at 00:34:01 UTC, vino wrote: //auto a = Array!string("Aname"); // throws error auto b = Array!char("Bname");// works auto c = Array!string("Aname", "Bname"); // works ... Looks to me like when it receives a single range it expects the elements of that range to match the type. Yes, the first overload fails to match because U is inferred as immutable(char) rather than string: this(U)(U[] values...) if (isImplicitlyConvertible!(U, T)) This is because a single array can be passed to a typesafe variadic parameter rather than elements of that array type. And then immutable(char) doesn't convert to string. I think a non-variadic overload could be added to make it work as expected.
Re: Ideas to reduce error message size?
On Wednesday, 30 August 2023 at 09:24:21 UTC, Paolo Invernizzi wrote: src/api3.d(49):called from here: `checkSql(Schema("public", src/dget/db.d(276): Error: template instance `api3.forgeSqlCheckerForSchema!(Schema("public", **BAZILLIONS of lines**> error instantiating ``` The compiler could limit the call expression to a few lines unless the verbose flag is passed. A similar problem exists when calling a function literal which errors, the whole body is printed which can be long.
Re: toLower
On Thursday, 17 August 2023 at 09:28:05 UTC, Joel wrote: .map!(std.uni.toLower) .sort!"aonlineapp.d(8): Error: none of the overloads of template `std.algorithm.sorting.sort` are callable using argument types `!("a /dlang/dmd/linux/bin64/../../src/phobos/std/algorithm/sorting.d(1925):Candidate is: `sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range r)` with `less = "a `map` generates a range `r` whose elements can be accessed by mutable reference only if the result of calling the map function (on a source element) is a mutable reference. But `std.uni.toLower` returns by value, and `sort` requires `r.front` to be a mutable reference. I'll look at improving the docs.
Re: Why is GC.collect `pure`
On Wednesday, 2 August 2023 at 17:55:12 UTC, Nick Treleaven wrote: On Wednesday, 2 August 2023 at 17:52:00 UTC, Nick Treleaven wrote: Now I'm wondering why those functions are marked `pure` - they must affect the GC's bookkeeping state. I guess it was because the GC's internal state is not supposed to be observable outside internal GC functions. I find it harder to accept some of those than `GC.malloc` being pure, because GC.disable and GC.enable will affect how long future allocations will take. That latency can be significant and observed by the program. Also conceptually they are changing GC state.
Re: Why is GC.collect `pure`
On Wednesday, 2 August 2023 at 17:52:00 UTC, Nick Treleaven wrote: Now I'm wondering why those functions are marked `pure` - they must affect the GC's bookkeeping state. Here's the pull that added it: https://github.com/dlang/druntime/pull/3561
Re: Why is GC.collect not @safe?
On Wednesday, 2 August 2023 at 13:27:50 UTC, Steven Schveighoffer wrote: On 8/2/23 7:40 AM, Nick Treleaven wrote: Presumably an allocation like `new T` (for a type with a @safe constructor) can be made anywhere a call to `GC.collect` can be made, which may trigger a collection. So why isn't `GC.collect` marked @safe? It should be. Maybe historical reasons? One possible (but wrong) reason is that destructors can be unsafe. But you are correct in that allocation can cause a collection. OK, thanks. I've made a pull to add `@safe` for enable, disable, collect, minimize: https://github.com/dlang/dmd/pull/15493/files Now I'm wondering why those functions are marked `pure` - they must affect the GC's bookkeeping state.
Re: How to free memory ater use of "new" to allocate it.
On Sunday, 16 July 2023 at 18:18:08 UTC, Alain De Vos wrote: 12 │ ~this(){ 13 │ writeln("Free heap"); 14 │ import object: destroy; 15 │ import core.memory: GC; 16 │ i=null; // But How to force GC free ? Firstly, be careful with class destructors and GC managed objects. The memory referenced by `i` may already have been freed by the GC when the class destructor is called - see: https://dlang.org/spec/class.html#destructors If you want to free GC memory when you know the allocation is still live, you can call __delete: https://dlang.org/phobos/core_memory.html#.__delete import std.stdio: writeln; ```d void main() { int[] i=null; writeln("Allocate heap"); i=new int[1]; i[9000]=5; import core.memory; const p = i.ptr; assert(GC.addrOf(p) !is null); writeln("Free heap"); __delete(i); assert(GC.addrOf(p) is null); } ```
Re: Evolving the D Language
On Sunday, 9 July 2023 at 18:51:01 UTC, IchorDev wrote: On Friday, 7 July 2023 at 13:19:51 UTC, Nick Treleaven wrote: Changing the syntax just for an obsolete feature would send the wrong message. [...] cent and ucent are already an error as of 2.100. Were they even implemented? Clearly you're not looking at this the same way as me, [or Walter](https://github.com/dlang/dmd/pull/15393). Fixing old code isn't the only upside to resurrecting old features. I thought Walter was asking for features that should be changed from deprecated to obsolete, it seems I was wrong. First thing, I think all languages should support binary, octal, decimal and hexadecimal literals as a baseline. Octal is probably the least important of them, but can still be plenty useful in its own right. Generally programmers can count in binary and decimal, hex somewhat. Not octal. You technically don't need *any* numerical literals at all in D, you could make all of them with string-to-number templates. You could take such an approach to just about everything in D, actually! On the other hand, people working on low-level Linux code might be pretty appalled to find out that they can't simply use octal literals to represent file permissions in D. Maybe because they're used to working in languages that don't have D's CTFE abilities. Octals are still rare. There are other literals, not all literals can be supported in the language. So the better solution for less common literals is to embrace the library pattern and dogfood it. C++ has user-defined literal support. D doesn't need that. ... There are a few D features that were poorly implemented (or not implemented at all), and then simply removed instead of being fully reconsidered. You might say that for many, they were indeed reconsidered, and then added to Phobos instead. Now some of these features pre-date BetterC, of course, but I am a regular BetterC user. A feature being moved to Phobos translates to "you don't get to use this in most of your code anymore" for me. `octal` could have been added to druntime, or you can copy the code. For betterC there's probably quite a lot of stuff in Phobos that works with betterC, so that is a general problem. I'm not a user of complex or imaginary types, but I don't see why they needed to be removed from D, were they a huge burden to maintain compared to being in Phobos? It depends whether you value language simplification and dogfooding.
Re: Evolving the D Language
On Friday, 7 July 2023 at 10:57:57 UTC, IchorDev wrote: Hexstring literals, They were first deprecated on Mar 01, 2018: https://dlang.org/changelog/2.079.0.html#hexstrings And removed in 2.086, so it's probably unlikely that any maintained code is using them. complex and imaginary floating point types & the corresponding literals, Deprecated in 2.097, maybe a good candidate to obsolete instead. built-in 128-bit integer types, cent and ucent are already an error as of 2.100. Were they even implemented? and octal literals, I think could all be added back to D without causing much detriment to D users who don't want to use them. ... 2. Ideally octal literals would have a better syntax. (e.g. "0o123") Changing the syntax just for an obsolete feature would send the wrong message. People rarely use octal so it doesn't need to be in the language, library is enough. The C syntax is indeed bug prone - leading zero.
Re: Evolving the D Language
On Friday, 7 July 2023 at 10:45:33 UTC, Guillaume Piolat wrote: alias this was a relatively bad idea, even if an iconic feature. I don't remember people from outside the community being impressed by alias this. There was no way to rewrite the code without breaking dependent code. That should not happen with a routine compiler release. We have the right to backtrack on bad ideas instead of keeping them forever. Marking a feature as obsolete doesn't mean it has to be supported forever. Presumably at some point support will be dropped. Possibly obsolete features could become deprecations before they are actually removed. The current deprecation system is very good. For something like alias this in classes, making it obsolete instead of deprecated signals that the feature won't be removed in 20 months (based on a 2-month release cycle, 10 release deprecation cycle as standard).
Re: is ref inout redundant in: ref inout(T) opIndex(size_t index)
On Monday, 19 June 2023 at 18:19:18 UTC, mw wrote: 2) `inout T` alone Steve covered everything, though you might also like to read the inout spec: https://dlang.org/spec/const3.html#inout
Re: Given an object, how to call an alias to a member function on it?
On Wednesday, 3 May 2023 at 11:26:00 UTC, ag0aep6g wrote: On 03.05.23 13:13, Nick Treleaven wrote: void fun(alias method)(C c) { void delegate() dg = dg(); } No, it doesn't. You're not using the alias. You're just accessing `c.method` directly. If the actual method weren't called "method", you'd get an error. Sorry, you're right.
Re: Given an object, how to call an alias to a member function on it?
On Tuesday, 2 May 2023 at 13:06:41 UTC, ag0aep6g wrote: void fun(alias method)(C c) { void delegate() dg; dg.funcptr = dg.ptr = cast(void*) c; dg(); } This also works: void fun(alias method)(C c) { void delegate() dg = dg(); }
Re: Why are globals set to tls by default? and why is fast code ugly by default?
On Monday, 27 March 2023 at 08:44:41 UTC, wjoe wrote: e.g.: It used to be faster to ... - pre-calculate sin/cos tables, now the memory look up cost more cycles than the calculation itself ... - only redraw the parts of the screen that changed, now the branching is slower than to redraw everything Good to know, thanks. another example is sorting - Alexei wrote a blog post about how a stupid and slow sorting algorithm now performs better in multi threading. Maybe someone remembers the title/url of the post ? Not sure, but that reminds me of Andrei's blog on partitioning (for quicksort): https://dlang.org/blog/2020/05/14/lomutos-comeback/ The algorithm traditionally considered slower can be faster because it can be optimized to work better with branch prediction.
Re: Why are globals set to tls by default? and why is fast code ugly by default?
On Sunday, 26 March 2023 at 20:36:37 UTC, ryuukk_ wrote: Golang doesn't even have thread local storage, yet they do very well Go doesn't have a solution to preventing data races at compile time, they just say don't share memory. But what if you accidentally share memory? That is *very* easy to do in Go. You and your users are out of luck. All you can do is run the race detector and pray that you happen to test all the code paths with it that might have data races: The race detector only finds races that happen at runtime, so it can't find races in code paths that are not executed https://go.dev/doc/articles/race_detector
Re: Why are globals set to tls by default? and why is fast code ugly by default?
On Sunday, 26 March 2023 at 20:39:21 UTC, ryuukk_ wrote: if my code doesn't do threads, why should i put my variable into TLS? I don't think writing __gshared is much of a burden. You can use -vtls to print out all variables that are TLS, and add that to an automated test to check you don't have any accidentally. I have thought before that a --no-threads compiler switch that does not link the key thread functions but makes __gshared the default might be a good enhancement for your use case. Then if you accidentally call some code that uses std.parallelism internally you would get a link error. If i want fast code, why should i make use of ugly syntax? 1. If you want fast code, why aren't you using threads? 2. By default D supports threads and accidental data races are far worse than ugly syntax.
Re: Why are globals set to tls by default? and why is fast code ugly by default?
On Sunday, 26 March 2023 at 20:39:21 UTC, ryuukk_ wrote: if my code doesn't do threads, why should i put my variable into TLS? I don't think writing __gshared is a huge burden. You can use -vtls to print out all variables that are TLS, and add that to an automated test to check you don't have any accidentally. I have thought before that a --no-threads compiler switch that does not link the key thread functions but makes __gshared the default might be a good option for your use case. Then if you accidentally call some code that uses std.parallelism internally you would get a link error. If i want fast code, why should i make use of ugly syntax? By default D supports threads and accidental data races are far worse than ugly syntax.
Re: Why are globals set to tls by default? and why is fast code ugly by default?
On Sunday, 26 March 2023 at 18:07:03 UTC, ryuukk_ wrote: What i find even more weird is writing fast code is ugly in D Look at this ugly code ```D __gshared int fast_code_ugly; ``` Because it should be rare that __gshared is used. And if you need it, you won't be worried about how the storage class looks because you'll be concentrating on if your design is thread-safe. It should be the opposite Then by default, @safe code can not access global variables and there can easily be accidental races between threads.
Re: templates and traits
On Saturday, 18 March 2023 at 19:22:07 UTC, Chris Katko wrote: ... So there's multiple sub-problems to solve. I asked this years ago, and got 90% of the way done and then lost the code and cannot find the original forum post. Maybe it was this?: https://forum.dlang.org/post/dqzxnctucwvyhstfz...@forum.dlang.org
Re: Is comparison of shared data thread-safe?
On Thursday, 16 March 2023 at 12:32:34 UTC, Nick Treleaven wrote: With -preview=nosharedaccess, I get: int y = 2; shared int x = y; // OK assert(x == 2); // no error y = x; // error This also does not error: ```d bool b = x == 3; ``` Filed: https://issues.dlang.org/show_bug.cgi?id=23783
Is comparison of shared data thread-safe?
With -preview=nosharedaccess, I get: int y = 2; shared int x = y; // OK assert(x == 2); // no error y = x; // error So for the assignment to y, reading x is an error and atomicLoad should be used instead. But is it an oversight that reading x in the assert is not an error? I have also found this in a unittest in core.atomic: shared(size_t) i; atomicOp!"+="(i, cast(size_t) 1); assert(i == 1); Is the assert somehow thread-safe?
Re: Non-ugly ways to implement a 'static' class or namespace?
On Friday, 20 January 2023 at 11:28:23 UTC, thebluepandabear wrote: ``` final abstract class Algo { void drawLine(Canvas c, Pos from, Pos to) { .. }; } ``` This solution seems like a bit of a hack, which is why I don't like it. Interesting solution if you put `static:` in there. Alternatively you could create a module, but then it would just be a function without a clear type. Why do you want a type? Is anyone aware of a non-ugly way to implement a 'static' class or namespace? Use a struct and put `static:` after the opening brace. That's what GC is in core.memory.
Re: Where I download Digital Mars C Preprocessor sppn.exe?
On Monday, 23 January 2023 at 17:15:30 UTC, Nick Treleaven 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 Found this thread by googling `dlang sppn.exe`. For the record, it can be obtained from sppn.zip here: http://ftp.digitalmars.com/ I didn't have it for some reason even though latest dmc is installed. I then got some weird errors building druntime: std::array not supported by DMC std::basic_string_view not supported by DMC I figured that dmc was not correctly installed (not sure why). So I downloaded dmc.zip which fixed it.
Re: D Contributor Tutorials Part 1 - Building the Compiler From Source - Windows
On Sunday, 22 January 2023 at 12:51:53 UTC, Nick Treleaven wrote: sppn.exe src\core\stdc\errno.c -HIsrc\importc.h -ED -oerrno.i -I. Error: C preprocess command sppn.exe failed for file src\core\stdc\errno.c, exit status 1 failed launching sppn.exe src\core\stdc\errno.c -HIsrc\importc.h -ED -oerrno.i -I. Turned out dmc wasn't correctly installed. I downloaded dmc.zip which fixed it. But chrome says 'Your connection is not private' and won't let me download that even if I look under Advanced. I also tried curl: ``` curl: (60) SSL: no alternative certificate subject name matches target host name 'ftp.digitalmars.com' Fixed by updating & using Firefox.
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 Found this thread by googling `dlang sppn.exe`. For the record, it can be obtained from sppn.zip here: http://ftp.digitalmars.com/ I didn't have it for some reason even though latest dmc is installed.
Re: D Contributor Tutorials Part 1 - Building the Compiler From Source - Windows
On Sunday, 8 January 2023 at 11:27:14 UTC, Mike Parker wrote: In this first tutorial of the series, he gives an overview of what happens when compiling a D source file, then shows how to set up an environment from which to build dmd and the standard library/runtime binary. The next video will use this setup to start making changes to dmd. Thanks, this is great (for posix builds). However I'm not sure the Windows instructions in the video are correct. It is good Dennis mentioned to use DM make as the wiki only mentioned that for the VS build instructions (I have updated it to make it clear). I tried running `make -f win32.mak` from the phobos root and got this: ``` Error: don't know how to make '../dmd/druntime/lib/druntime.lib' ``` So it seems on Windows druntime still does have to be built before that (unlike on Linux). So I ran `make -f win32.mak` from dmd/druntime and got this error: ``` ..\compiler\..\generated\windows\release\32\dmd -c -of=errno_c_32omf.obj -m32omf -conf= -O -release -preview=dip1000 -preview=fieldwise -preview=dtorfields -inline -w -Isrc -Iimport -v -P=-I. src\core\stdc\errno.c predefs DigitalMars LittleEndian D_Version2 all Windows Win32 CRuntime_DigitalMars CppRuntime_DigitalMars D_InlineAsm D_InlineAsm_X86 X86 D_ModuleInfo D_Exceptions D_TypeInfo D_HardFloat D_Optimized binary..\compiler\..\generated\windows\release\32\dmd.exe version v2.101.0-rc.1-72-g5c3dafa06f config DFLAGS(none) include src\importc.h sppn.exe src\core\stdc\errno.c -HIsrc\importc.h -ED -oerrno.i -I. Error: C preprocess command sppn.exe failed for file src\core\stdc\errno.c, exit status 1 failed launching sppn.exe src\core\stdc\errno.c -HIsrc\importc.h -ED -oerrno.i -I. ``` I don't know what `sppn.exe` is. --- Before trying phobos win32.mak I also tried the win64.mak but it needs `cl.exe` which apparently I can get here: https://ftp.digitalmars.com/bup.zip But chrome says 'Your connection is not private' and won't let me download that even if I look under Advanced. I also tried curl: ``` curl: (60) SSL: no alternative certificate subject name matches target host name 'ftp.digitalmars.com' More details here: https://curl.se/docs/sslcerts.html curl failed to verify the legitimacy of the server and therefore could not establish a secure connection to it. To learn more about this situation and how to fix it, please visit the web page mentioned above. ```
Re: D Contributor Tutorials Part 1 - Building the Compiler From Source
On Sunday, 8 January 2023 at 19:28:59 UTC, ryuukk_ wrote: The Wiki is outdated and mentions tools that do not exist https://wiki.dlang.org/Building_under_Windows I haven't been able to build druntime on Windows. I have just updated the page to make it clear that DM make is needed even when not using Visual Studio. Which tools does it mention that don't exist? I updated it with the little information i had but that still wasn't enough to be able to build the whole thing I even asked on the forum for some help, wich was met with silence https://forum.dlang.org/thread/aapqglgpugyuimhof...@forum.dlang.org?page=1 Well some people replied, but it didn't really help.
Re: Preventing nested struct destructor accessing stack frame
On Tuesday, 20 December 2022 at 06:31:09 UTC, ag0aep6g wrote: On 16.12.22 14:07, Nick Treleaven wrote: This seems to work: ~this() @trusted { if ( > cast(void*)1024) i++; } It would be better if there was a struct property to get the context pointer though. A quick test suggests that the context pointer is the last item in `tupleof`. So this might do the trick: ~this() { if (this.tupleof[$ - 1] !is null) i++; } I don't know if it's guaranteed to work though. Might be an implementation detail. Great, thanks. The struct tupleof docs just link to the class tupleof docs, which say: The order of the fields in the tuple matches the order in which the fields are declared. So I think for a struct the context pointer has to come after any fields.
Re: Unique!struct bug - Re: unique_ptr | Unique for autoclose handle
On Thursday, 15 December 2022 at 20:12:12 UTC, Ali Çehreli wrote: I think this is a bug because the documentation clearly talks about destroying the object: OK: https://github.com/dlang/phobos/pull/8651 > do we need to do some kind of deprecation? The behavior is so different from the intention that I don't think anybody is using Unique anyway. :o) Yes, at least for structs.
Re: Preventing nested struct destructor accessing stack frame
On Friday, 16 December 2022 at 12:17:40 UTC, Nick Treleaven wrote: It seems destroy clears the context pointer. Is there a way to test if the context pointer is null in the dtor, to prevent the increment? This seems to work: ~this() @trusted { if ( > cast(void*)1024) i++; } It would be better if there was a struct property to get the context pointer though.
Preventing nested struct destructor accessing stack frame
This code segfaults when the GC calls the dtor after the unittest succeeds: ```d unittest { int i; struct S { ~this() { i++; } } (*new S).destroy; } ``` It seems destroy clears the context pointer. Is there a way to test if the context pointer is null in the dtor, to prevent the increment?
Re: pointer escaping return scope bug?
On Thursday, 15 December 2022 at 20:02:38 UTC, Nick Treleaven wrote: auto f() return @trusted => p ? p : v.ptr; Whoops, that can't be @trusted unless I `assert(p)`.
Re: pointer escaping return scope bug?
On Saturday, 19 November 2022 at 15:24:33 UTC, Dukc wrote: On Saturday, 19 November 2022 at 15:02:54 UTC, Nick Treleaven wrote: OK, so how do I make `lf` implicitly scope? Have the `int*` inside it to point to a local, or assign another `scope int*` to it. Thanks, this works: ```d @safe: struct S { int* p; int[0] v; // dummy storage auto f() return @trusted => p ? p : v.ptr; } void main() { int* p; { S s = S(new int); p = s.f; // error } } ```
Unique!struct bug - Re: unique_ptr | Unique for autoclose handle
On Wednesday, 14 December 2022 at 17:41:07 UTC, Ali Çehreli wrote: I've never used Unique but I think it has a bug (or a design issue?): Its destructor is the following: ~this() { if (_p !is null) { destroy(_p); _p = null; } } Because _p is a pointer, destroy(_p) will not dereference and destroy what it points to. I think this is a bug with Unique. I think it should do destroy(*_p); Now filed: https://issues.dlang.org/show_bug.cgi?id=23561 Do you think it's OK to just fix this or do we need to do some kind of deprecation?
Re: printf, writeln, writefln
On Thursday, 8 December 2022 at 17:39:58 UTC, Ali Çehreli wrote: On 12/8/22 08:21, Salih Dincer wrote: > void stringCopy(Chars)(string source, > ref Chars target) >sample.stringCopy = cTxt; // disappeared ? char Nothing disappeared on my system. (?) Going off-topic, I find the expression above extremely confusing. I am used to assignment expression changing the value of the left hand side, but that expression changes cTxt. Very confusing... Such obfuscations make it very hard for me to understand what the code is trying to demonstrate. Yes, with function call syntax it's more understandable if an argument is modified. It was bizarre and confusing that assignment syntax was implemented for functions and methods not explicitly marked with @property.
Re: How ptr arithmitic works??? It doesn't make any sense....
On Sunday, 4 December 2022 at 16:33:35 UTC, rempas wrote: struct MemoryBlock { char* ptr; ulong length; } (MemoryBlock.sizeof is 16 on my 64-bit system). void* ptr = cast(void*)0x7a7; void* right() { return cast(MemoryBlock*)(ptr + MemoryBlock.sizeof); // Cast the whole expression between paranthesis. Got the right value! } The above adds 16 bytes to ptr. void* wrong() { return cast(MemoryBlock*)ptr + MemoryBlock.sizeof; // First cast the `ptr` variable and then add the number. Got a wronge value... } The above adds 16 * MemoryBlock.sizeof bytes (16 * 16) to ptr, because ptr is cast first. Should be `+ 1` to be equivalent. https://dlang.org/spec/expression.html#pointer_arithmetic "the resulting value is the pointer plus (or minus) the second operand **multiplied by the size of the type pointed to by the first operand**." char* return_address_wrong() { MemoryBlock* local_ptr = cast(MemoryBlock*)ptr; return cast(char*)(local_ptr + MemoryBlock.sizeof); // Casted the whole expression. BUT GOT THE WRONG VALUE Why??? } Because you are adding to a pointer that points to a 16-byte block, rather than a void* which points to a single byte. char* return_address_right() { MemoryBlock* local_ptr = cast(MemoryBlock*)ptr; return cast(char*)local_ptr + MemoryBlock.sizeof; // Now I first casted the `local_ptr` variable and then added the number but this time this gave me the right value } The casted pointer points to a single byte.
Re: pointer escaping return scope bug?
On Friday, 25 November 2022 at 15:03:57 UTC, ShadoLight wrote: I don't grok how `lf` can survive the local scope. Or am I missing something? Perhaps because the local scope is not pushed as a separate (anonymous) function on the stack... if true then, yes, then `lf` will indeed have the same physical lifetime as main (and `p`)...? On the other hand, if you add a destructor to `LockedFile`, it will be invoked at the end of the local scope, not the end of main. Yes, the actual code does have a destructor. It's analogous to this: ```d @safe: struct S { private int* fps; auto fp() return scope => fps; this(int) { fps = new int; } @disable this(); @disable void opAssign(S); ~this() @trusted // how do we make this safe? { import core.memory; GC.free(fps); } } void main() { int* p; { auto lf = S(5); p = lf.fp; } assert(p != null); // address escaped } ``` That compiles with -dip1000. D doesn't seem to have a way to prevent the memory outliving the struct. Just to note there is another problem when the struct is destroyed explicitly whilst the `fp` result is still live. But that could be solved by making `object.destroy` and `std.algorithm.move` be restricted to @system for certain structs like this one (either opt-in or some other mechanism). The first problem doesn't seem to have a solution.
Re: pointer escaping return scope bug?
On Saturday, 19 November 2022 at 14:52:23 UTC, ag0aep6g wrote: That's essentially just a function that returns its pointer parameter. So the program boils down to this: @safe: int* fp(return scope int* p) { return p; } void main() { int* p; { auto lf = new int; p = fp(lf); } assert(p != null); // address escaped } Which is fine, as far as I can tell. `lf` is not `scope`. And when you pass it through `fp`, the result is still not `scope`. So escaping it is allowed. You do get an error when you make `lf` `scope` (explicitly or implicitly). So everything seems to be in order. OK, so how do I make `lf` implicitly scope?
pointer escaping return scope bug?
Hi, The following seems like a bug to me (reduced code, FILE* changed to int*): ```d @safe: struct LockedFile { private int* fps; auto fp() return scope => fps; } void main() { int* p; { auto lf = LockedFile(new int); p = lf.fp; } assert(p != null); // address escaped } ``` There's no error with -dip1000. I'll file this unless I overlooked something.
Re: Hipreme's #2 Tip of the day - Reducing .di files dependency
On Sunday, 23 October 2022 at 20:12:46 UTC, Hipreme wrote: For reducing a D Interface file dependency when generating it with the `-H` flag for DMD, you can't import a module on the top level. Take a look at that example: This would make a nice blog post if you have one ;-)
Re: Remove elements without losing capacity
On Tuesday, 4 October 2022 at 18:18:41 UTC, Ali Çehreli wrote: A related topic is how the "end slice" never loses that capacity: void main() { auto a = [ 1, 2 ]; auto b = a; assert(a.capacity != 0); assert(b.capacity != 0); b.length--; assert(b.capacity == 0); assert(a.capacity != 0);// <-- Preserved } Aside: .capacity is an expensive operation that requires some levels of table lookups in the druntime. A data structure would benefit a lot if it kept its own capacity as a member variable. I've now made a pull to document this: https://github.com/dlang/dlang.org/pull/3445
Re: rotate left an array
On Monday, 3 October 2022 at 18:09:05 UTC, Fausto wrote: Hello all, I am trying to rotate left an array. I found a very basic way, and I am not sure if there is something clever than this :) maybe using slices... Here we can't use slice assignment instead of the inner loop because that doesn't work for an overlapping slice. (Instead there's `copy` in std.algorithm). The algorithm you wrote doesn't scale the best for speed - yours is the second one mentioned here: https://www.geeksforgeeks.org/array-rotation/ Phobos has `bringToFront(arr[0..2], arr[2..$])` which does the same thing as a `rotate(arr, 2)` function. It seems to use the third algorithm from the link (or at least has the same time and space complexity). The first algorithm may also work better in some cases, when swapping is expensive or when the result is duplicated anyway.
Re: DIP 1043---Shortened Method Syntax---Accepted
On Saturday, 24 September 2022 at 08:45:33 UTC, Dukc wrote: On Wednesday, 21 September 2022 at 10:39:27 UTC, Mike Parker wrote: The fact that the feature was already implemented behind a preview switch carried weight with Atila. He noted that, if not for that, he wasn't sure where he would stand on adding the feature, but he could see no reason to reject it now. If there is no reason to reject an already-implemented feature, there's no reason to to reject it as non-implemented either. Not just already implemented, but reviewed and merged by existing maintainers. It shows the feature was considered by trusted colleagues to be worth adding as a preview. If it feels like it's too much work to implement an otherwise good DIP, it should be accepted on the condition that someone does it, not rejected IMO. DIPs for semantic features are much easier to review when there's an implementation so people can play with the feature and see how it interacts with the existing language. Basically the burden should be on the advocates to make their case, not on the maintainers to investigate an idea.
Re: Linker Error with Template Function
On Tuesday, 13 September 2022 at 03:00:17 UTC, Kyle Ingraham wrote: Any suggestions for being able to call one function for any instance given but maintain flexible return types? Not sure if it helps, but you can define final methods in an interface, which can call virtual interface methods: ```d interface PathConverter { string getValue(); final T toD(T)() { import std.conv : to; return to!T(getValue()); } } ``` Not tested as AFK.
Re: Tracing out error that causes compiler crash
On Sunday, 4 September 2022 at 20:48:52 UTC, solidstate1991 wrote: What do I pass as the tester? You can use a script as described here: https://github.com/CyberShadow/DustMite/wiki/Detecting-a-segfault-in-dmd-itself