mixin template's alias parameter ... ignored ?

someone someone at somewhere.com
Mon Jul 12 23:45:57 UTC 2021


On Monday, 12 July 2021 at 23:18:57 UTC, jfondren wrote:
> On Monday, 12 July 2021 at 22:35:27 UTC, someone wrote:
>>> Bug: `scope` makes no sense if you want to return 
>>> `lstrSequence` (throughout).
>>
>> Teach me please: if I declare a variable right after the 
>> function declaration like this one ... ain't scope its default 
>> visibility ? I understand (not quite sure whether correct or 
>> not right now) that everything you declare without explicitly 
>> stating its visibility (public/private/whatever) becomes scope 
>> ie: what in many languages are called a local variable. What 
>> actually is the visibility of lstrSequence without my scope 
>> declaration ?
>
> Local variables don't have a visibility in the sense of public 
> or private. They do have a 'scope' in the general computer 
> science sense, and a variable can be said to be in or out of 
> scope at different points in a program, but this is the case 
> without regard for whether the variable is declared with D's 
> `scope`. What `scope` says is 
> https://dlang.org/spec/attribute.html#scope
>
>>For local declarations, scope ... means that the destructor for 
>>an object is automatically called when the reference to it goes 
>>out of scope.
>
> The value of a normal, non-scope local variable has a somewhat 
> indefinite lifetime: you have to examine the program and think 
> about operations on the variable to be sure about that 
> lifetime. Does it survive the function? Might it die even 
> before the function completes? Does it live until the next GC 
> collection or until the program ends? These are questions you 
> can ask.
>
> For a `scope` variable, the lifetime of its value ends with the 
> scope of the variable.
>
> Consider:
>
> ```d
> import std.stdio : writeln, writefln;
> import std.conv : to;
> import core.memory : pureMalloc, pureFree;
>
> class Noisy {
>     static int ids;
>     int* id;
>     this() {
>         id = cast(int*) pureMalloc(int.sizeof);
>         *id = ids++;
>     }
>
>     ~this() {
>         writefln!"[%d] I perish."(*id);
>         pureFree(id);
>     }
> }
>
> Noisy f() {
>     scope n = new Noisy;
>     return n;
> }
>
> void main() {
>     scope a = f();
>     writeln("Checking a.n...");
>     writefln!"a.n = %d"(*a.id);
> }
> ```
>
> Which has this output on my system:
>
> ```d
> [0] I perish.
> Checking a.n...
> Error: program killed by signal 11
> ```
>
> Or with -preview=dip1000, this dmd output:
>
> ```d
> Error: scope variable `n` may not be returned
> ```
>
> the lifetime of the Noisy object bound by `scope n` is the same 
> as the scope of the variable, and the varaible goes out of 
> scope when the function returns, so the Noisy object is 
> destructed at that point.

Some days ago I assumed scope was, as I previously stated, the 
local default scope, and explicitly added scope to all my *local* 
variables. Soon afterward I encountered a situation which gave me 
the "program killed by signal 11" which I did not 
fully-understand why it was happening at all, because it never 
occurred to me it was connected to my previous scope refactor. 
Now I understand.

Regarding -preview=dip1000 (and the explicit error description 
that could have helped me a lot back then) : DMD man page says 
the preview switch lists upcoming language features, so DIP1000 
is something like a D proposal as I glanced somewhere sometime 
ago ... where do DIPs get listed (docs I mean) ?

So, every *local* variable within a chunk of code, say, a 
function, should be declared without anything else to avoid this 
type of behavior ? I mean, anything in code that it is not 
private/public/etc.

Or, as I presume, every *local* meaning *aux* variable that won't 
need to survive the function should be declared scope but *not* 
the one we are returning ... lstrSequence in my specific case ?

Can I declare everything *scope* within and on the last line 
using lstrSequence.dup instead ? dup/idup duplicates the variable 
(the first allowing mutability while the second not) right ?

Which one of the following approaches do you consider best 
practice if you were directed to explicitly state as much 
behavior as possible ?

Your reply with this example included was very illustrating to me 
-right to the point.

Thanks a lot for your time :) !


More information about the Digitalmars-d-learn mailing list