Re: Run-time setting of immutable variable?
On 9/2/21 9:01 AM, DLearner wrote: Suppose there is a variable that is set once per run, and is (supposed) never to be altered again. An accessor function can be a solution, which supports your other comment about data potentially mutating by other means: // Assume these are in a module // // This is private; you can even name it arr_. private ubyte[10] arr; // This is the accessor: public const(ubyte)* arrPtr() { return arr.ptr; } // void main() { *arrPtr = 42; // Compilation ERROR; good. } Ali
Re: Run-time setting of immutable variable?
On 9/2/21 1:17 PM, DLearner wrote: I am looking for a mutable Arr but would like an immutable ArrPtr. Then you want const not immutable. Here is the reason: ```d void main() { int x = 5; immutable int *ptr = cast(immutable int *)&x; assert(*ptr == 5); // ok x = 6; assert(*ptr == 5); // what happens here? } ``` Depending on optimizations and compiler constant folding, that second assert may pass. immutable means "I can never change and *everything I point at* can never change". The compiler is free to use this knowledge to avoid redoing calculations it has already done. I tknows that `*ptr == 5` already, and that can never change, so it just doesn't even bother with the second assert. However, make ptr *const*, and now not only do you not need the cast, but the second assert will fail as expected. ``` `Arr` is not immutable, so `ArrPtr` shouldn't point at it if it's immutable. ``` Surely there is no inconsistency - at run time the array is in a fixed place, so ArrPtr is (or at least should be) a constant, but the contents of the array can vary as the program runs. In D, const and immutable are transitive, which means that you can't have a pointer that is const, but allows changing what it points at. So while a const pointer *may* work for your purposes, you may want a specialized type, or a property function. It depends on how you intend to use `ArrPtr`. Others have given good answers to this problem. -Steve
Re: template parameters
On Thu, Sep 02, 2021 at 02:28:23PM -0700, Charles Hixson via Digitalmars-d-learn wrote: [...] > -- > Javascript is what you use to allow third part programs you don't know > anything about and doing you know not what to run on your computer. ROFL! I'm st^Wborrowing this for my quotes file. ;-) T -- "How are you doing?" "Doing what?"
Re: template parameters
Thanks. See below for what I did. On 8/29/21 5:05 PM, Ali Çehreli via Digitalmars-d-learn wrote: On 8/29/21 3:31 PM, Charles Hixson wrote: > Thanks. I going to have to study: > > enum supportsCall = isIntegral!(typeof(T.init.%s())); > > > for awhile to make any sense of that, but it looks like just what I was > looking for. Trying to explain with comments: // This is an eponymous template because it contains // a symbol that's the same as the name of this template. // And that symbol is 'supportsCall'. So, this template // will be whatever that symbol is. (In this case, it // will be a compile-time know entity: 'enum bool'.) template supportsCall(T, string func) { import std.format : format; import std.traits : isIntegral; // This is a string expression we will mix-in below. enum expr = format!q{ enum supportsCall = isIntegral!(typeof(T.init.%s())); }(func); // The above expression will be the following e.g. // for 'int' and for "ndx": // // enum supportsCall = isIntegral!(typeof(int.init.ndx())); // // So, it's determining whether the typeof the expression // int.init.ndx() is an integral. // // 'supportsCall' is a bool, which I could have made explicit: // // enum bool supportsCall = [...] // // You can prove it for yourself by "printing" the expression // at compile time: pragma(msg, expr); // Here is where we mix-in the expression into this template's // definition. mixin (expr); } Then the whole template can be used as a compile-time bool value. Ali I'm going to need to save that for the future. I ran into errors in other sections. I suspect that a general form would require static if tests in numerous routines. Anyway, if you're interested this is what I ended up with. (I think it's error free, but not all paths have been tested.) import std.algorithm : remove; import std.exception; import std.stdio; import std.traits : isIntegral; import utils; // this is for my randomized integer code based on time: rndT /** An Associative Array with some Randomization and Linear features. * Note: This is done in a simplified and not too generalized fashion so that I don't need to * figure out template parameters at the moment. It should be redone later, when my mastery * is better. The current version should work for classes and structs that have a function * int T.ndx() that returns a unique id. That id (called the key) is used as an AA index * to find the instance, with duplicates not being allowed. */ class AARL2 (T) { /** The associative array of cells, with the index as the key. */ T[int] aa; /** A linear array of cell key values. This is ordered by the order in which they were * inserted rather than by value. */ int[] rl; /** Create an AARL from an array of cells. The array must have no entries with duplicate * key values (i.e. cell.ndx). Currently this throws an exception. Consider how it could * be handled more gracefully. */ this (T[] inp) { foreach (T c; inp) { int key = c.ndx; enforce (key !in aa, "Attempt to insert a key already present."); aa[key] = c; rl ~= key; } } this () {} /** Access members by serial position of key. (Not the value of the key!) */ T at (int i) in { assert (i >= 0 && i < rl.length, "Index outside bounds"); } body { int key = rl[i]; return aa[key]; } /** This is a read-only count of number of entries. */ long length() { return aa.length; } bool opBinaryRight(string op)(int key) const if (op == "in") { return cast (bool)(key in aa); } bool opBinaryRight(string op)(T c) const if (op == "in") { return cast (bool)(c.ndx in aa); } /** Allow the [] operator to retrieve instances by key value. */ T opIndex(int key) { if (key in aa) return aa[key]; return null; } /** "append" an instance of T. */ void opOpAssign (string op)(T c) // if (op == "~=" && isIntegral!(typeof(T.init.ndx()) if (op == "~") { append (c); } /** "append" an instance of T. * Note: I need a better response to an attempt to add duplicates. */ void append (T c) { if (c is null) { stderr.writeln ("Attempt to add a null T to the AARL rejected."); return; } int key = c.ndx; if (key in aa) { aa[key] = c; } else { aa[key] = c; rl ~= key; } return; } /** Pop the most recently added T off the table. */ T pop () { if (rl.length < 1) return nu
Re: Dustmite and linking error
On Thursday, 2 September 2021 at 11:20:18 UTC, Vladimir Panteleev wrote: One way to get a very rough estimate is to take the square of the current reduction (.reduced directory), and divide it by the square of the original source. I meant the square of the size of the respective directory. (bytes / LOC / SLOC...) One week later it is still running (depth 22). If you are still on the first iteration, you may also try switching to the "careful" strategy.
Re: Run-time setting of immutable variable?
On Thu, Sep 02, 2021 at 05:17:15PM +, DLearner via Digitalmars-d-learn wrote: [...] > The following clean-compiled and produced the expected result: > ``` > ubyte[10] Arr; > > immutable void* ArrPtr; > shared static this() { > ArrPtr = cast(immutable void*)(&Arr[0]); > } Casting this to immutable is unsafe, because Arr is actually mutable. In D, const and immutable are transitive, so when you cast a pointer into immutable, you're basically promising that *both* the pointer *and* the data pointed to will never change. The compiler is free to assume that the data pointed to will never change, which may cause consistency problems if the data *does* change later. In cases like this, const is a better choice: const ensures that the pointer will not mutate and the pointed-to data cannot be mutated through this pointer, but the data *may* be mutated through another reference (e.g., by modifying Arr directly). [...] > I am looking for a mutable Arr but would like an immutable ArrPtr. In D, const and immutable are transitive, so you cannot do this (but see below). > ``` > `Arr` is not immutable, so `ArrPtr` shouldn't point at it if it's > immutable. > ``` > Surely there is no inconsistency - at run time the array is in a fixed > place, so ArrPtr is (or at least should be) a constant, but the > contents of the array can vary as the program runs. In this case, what you want is const, not immutable. Const means you cannot modify the pointer, and you cannot mutate the data through this pointer, but you *can* modify the array from a mutable reference. T -- You are only young once, but you can stay immature indefinitely. -- azephrahel
Re: Documentation generator is not working
On Thursday, 2 September 2021 at 17:34:59 UTC, Adam D Ruppe wrote: Anything after -run goes to your program not the compiler. Args to the compiler must be before -run. Thanks for the reply. Got the point now. :)
Re: Documentation generator is not working
On Thursday, 2 September 2021 at 17:20:55 UTC, Vinod K Chandran wrote: "dmd -run test.d -D" Anything after -run goes to your program not the compiler. Args to the compiler must be before -run.
Re: Run-time setting of immutable variable?
On Thursday, 2 September 2021 at 17:17:15 UTC, DLearner wrote: Surely there is no inconsistency - at run time the array is in a fixed place, so ArrPtr is (or at least should be) a constant, but the contents of the array can vary as the program runs. In the case of `immutable(T)* ArrPtr`, the contents of the pointed-to array cannot vary as the program runs. If it's immutable, nothing in the program ever mutates it. In the case of `const(T)* ArrPtr`, the contents of the pointed-to array can vary as the program runs, and the only restriction is that the array can't be mutated through ArrPtr. If what you mean is that you want the *pointer* to never change, `T * const ArrPtr` in C syntax, but that you don't care if the pointed-to array changes via ArrPtr or any other reference, then I don't think D can express this. You could make ArrPtr a function: ```d void main() { int[] xs = [1, 2, 3, 4]; int* p() { return &xs[2]; } p[0] = 0; assert(xs == [1, 2, 0, 4]); p++; // Error: ... not an lvalue and cannot be modified } ```
Re: Run-time setting of immutable variable?
If you want only address, you can keep it as size_t: ubyte[10] Arr; immutable size_t Address; static this() { Address = cast(size_t)(&Arr[0]); }
Re: Documentation generator is not working
On Thursday, 2 September 2021 at 16:26:19 UTC, jfondren wrote: What commands are you running? What you describe doing, works: ``` $ dmd -D file $ w3m -dump file.html|grep -A1 function A sample function. Let's check what we will get in documentation. abc - A simple string $ rm -fv file.html removed 'file.html' $ dmd -D file $ w3m -dump file.html|grep -A1 function A sample function. Let's check what we will get in documentation. abc - A simple string $ ``` Thanks for the reply. My command was the problem. I repeatedly used "dmd -run test.d -D" But now, I can see the html file when I use this -- "dmd -D test.d".
Re: Run-time setting of immutable variable?
On Thursday, 2 September 2021 at 16:46:46 UTC, Steven Schveighoffer wrote: On 9/2/21 12:01 PM, DLearner wrote: Suppose there is a variable that is set once per run, and is (supposed) never to be altered again. However, the value to which it is set is not known at compile time. Example below, variable is 'ArrPtr'; ``` ubyte[10] Arr; // immutable void* ArrPtr; void* ArrPtr; void main() { ArrPtr = cast(void*)Arr[0]; // modify ArrPtr> } ``` Is there a way of getting D to guarantee that ArrPtr is never modified after ``` ArrPtr = cast(void*)Arr[0]; ```] You shouldn't be doing this. `Arr` is not immutable, so `ArrPtr` shouldn't point at it if it's immutable. If you want to guarantee that `ArrPtr` never changes once set, yet still want it to point at mutable data, you need to use a type that does that (like a head mutable or "write once" type), which I believe doesn't exist in phobos. If you don't actually need to mutate the data via `ArrPtr`, you can make it const, and use H.S. Teoh's solution. But you should not use immutable, as the compiler implies that data pointed at is also immutable (and of course, you won't need casting). Make sure you use regular `static this`, not `shared static this`, as your fields are thread-local, not shared. -Steve The following clean-compiled and produced the expected result: ``` ubyte[10] Arr; immutable void* ArrPtr; shared static this() { ArrPtr = cast(immutable void*)(&Arr[0]); } void main() { import std.stdio; void* ArrPtr2; ArrPtr2 = cast(void*)(&Arr[0]); writeln("ArrPtr = ", ArrPtr); writeln("ArrPtr2 = ", ArrPtr2); // consistency test // ArrPtr = ArrPtr + 1; // mutability test - compile (correctly) failed when uncommented. ArrPtr2 = ArrPtr2 + 1; Arr[1] = 4; Arr[1] = 7; // mutability test } ``` The following produced deprecated warnings, but still seemed to work: ``` ubyte[10] Arr; immutable void* ArrPtr; static this() { ArrPtr = cast(immutable void*)(&Arr[0]); } void main() { import std.stdio; void* ArrPtr2; ArrPtr2 = cast(void*)(&Arr[0]); writeln("ArrPtr = ", ArrPtr); writeln("ArrPtr2 = ", ArrPtr2); // consistency test // ArrPtr = ArrPtr + 1; // mutability test on ArrPtr - compile (correctly) failed when uncommented. ArrPtr2 = ArrPtr2 + 1; Arr[1] = 4; Arr[1] = 7; // mutability test on Arr } ``` I am looking for a mutable Arr but would like an immutable ArrPtr. ``` `Arr` is not immutable, so `ArrPtr` shouldn't point at it if it's immutable. ``` Surely there is no inconsistency - at run time the array is in a fixed place, so ArrPtr is (or at least should be) a constant, but the contents of the array can vary as the program runs.
Re: Run-time setting of immutable variable?
On 9/2/21 12:01 PM, DLearner wrote: Suppose there is a variable that is set once per run, and is (supposed) never to be altered again. However, the value to which it is set is not known at compile time. Example below, variable is 'ArrPtr'; ``` ubyte[10] Arr; // immutable void* ArrPtr; void* ArrPtr; void main() { ArrPtr = cast(void*)Arr[0]; // } ``` Is there a way of getting D to guarantee that ArrPtr is never modified after ``` ArrPtr = cast(void*)Arr[0]; ```] You shouldn't be doing this. `Arr` is not immutable, so `ArrPtr` shouldn't point at it if it's immutable. If you want to guarantee that `ArrPtr` never changes once set, yet still want it to point at mutable data, you need to use a type that does that (like a head mutable or "write once" type), which I believe doesn't exist in phobos. If you don't actually need to mutate the data via `ArrPtr`, you can make it const, and use H.S. Teoh's solution. But you should not use immutable, as the compiler implies that data pointed at is also immutable (and of course, you won't need casting). Make sure you use regular `static this`, not `shared static this`, as your fields are thread-local, not shared. -Steve
Re: Documentation generator is not working
On Thursday, 2 September 2021 at 16:20:32 UTC, Vinod K Chandran wrote: Hi all, I am playing with ddoc. I wrote this code-- ```d import std.stdio : log = writeln; void main() { log("Experimenting with dDoc"); } /// A sample function. /// Let's check what we will get in documentation. /// abc - A simple string void sample(string abc) {log(abc);} ``` And then, compile it with "-D" switch. At first, I saw an html file is generated. But I deleted it and compiled again. This time, no html file is generated. What's wrong with this ? What commands are you running? What you describe doing, works: ``` $ cat file.d import std.stdio : log = writeln; void main() { log("Experimenting with dDoc"); } /// A sample function. /// Let's check what we will get in documentation. /// abc - A simple string void sample(string abc) {log(abc);} $ dmd -D file $ w3m -dump file.html|grep -A1 function A sample function. Let's check what we will get in documentation. abc - A simple string $ rm -fv file.html removed 'file.html' $ dmd -D file $ w3m -dump file.html|grep -A1 function A sample function. Let's check what we will get in documentation. abc - A simple string $ ```
Documentation generator is not working
Hi all, I am playing with ddoc. I wrote this code-- ```d import std.stdio : log = writeln; void main() { log("Experimenting with dDoc"); } /// A sample function. /// Let's check what we will get in documentation. /// abc - A simple string void sample(string abc) {log(abc);} ``` And then, compile it with "-D" switch. At first, I saw an html file is generated. But I deleted it and compiled again. This time, no html file is generated. What's wrong with this ?
Re: Run-time setting of immutable variable?
On Thu, Sep 02, 2021 at 04:01:19PM +, DLearner via Digitalmars-d-learn wrote: > Suppose there is a variable that is set once per run, and is > (supposed) never to be altered again. However, the value to which it > is set is not known at compile time. This is the classic use case of `immutable`. Using the example you gave, you'd move the initialization of ArrPtr into a static module constructor: immutable void* ArrPtr; shared static this() { ArrPtr = ...; // initialize it here } void main() { ... // ArrPtr is immutable from here on. } T -- Дерево держится корнями, а человек - друзьями.
Run-time setting of immutable variable?
Suppose there is a variable that is set once per run, and is (supposed) never to be altered again. However, the value to which it is set is not known at compile time. Example below, variable is 'ArrPtr'; ``` ubyte[10] Arr; // immutable void* ArrPtr; void* ArrPtr; void main() { ArrPtr = cast(void*)Arr[0]; // ArrPtr> } ``` Is there a way of getting D to guarantee that ArrPtr is never modified after ``` ArrPtr = cast(void*)Arr[0]; ``` Best regards
Re: Dustmite and linking error
On Thursday, 2 September 2021 at 11:04:12 UTC, JG wrote: Hi, We hit a linking error (after upgrading to dub 1.26.0). I thought I would try to use dustmite to create a reduced error test case. One week later it is still running (depth 22). I don't suppose there is anyway of determining when it will finish? One way to get a very rough estimate is to take the square of the current reduction (.reduced directory), and divide it by the square of the original source. For best performance, make sure that: 1) You are using the latest version from https://github.com/CyberShadow/DustMite 2) DustMite itself is built in release mode 3) You are using the -j switch to enable parallelism 4) You are running the reduction on a RAM disk or equivalent If you don't want to risk losing progress by putting everything (including the result directory) on a RAM disk, the latest bleeding-edge version on the "next" branch introduces a --temp-dir option. DustMite reductions can be stopped and resumed by pointing DustMite at the latest .reduced directory from a previous run.
Re: Dustmite and linking error
On Thursday, 2 September 2021 at 11:04:12 UTC, JG wrote: Hi, We hit a linking error (after upgrading to dub 1.26.0). I thought I would try to use dustmite to create a reduced error test case. One week later it is still running (depth 22). I don't suppose there is anyway of determining when it will finish? Possibly it's not a compiler error at all but a name-mangling change combined with some stale objects in your build.
Dustmite and linking error
Hi, We hit a linking error (after upgrading to dub 1.26.0). I thought I would try to use dustmite to create a reduced error test case. One week later it is still running (depth 22). I don't suppose there is anyway of determining when it will finish?