Re: dmd-2.078.2 problems with Ubuntu 17.10 32Bit

2018-02-12 Thread Martin Tschierschke via Digitalmars-d-learn

On Monday, 12 February 2018 at 21:18:01 UTC, Jordi Sayol wrote:
El 12/02/18 a les 21:56, Martin Tschierschke via 
Digitalmars-d-learn ha escrit:
I just started to play around with D again on my notebook at 
home and realized,

that I have a broken installation.
Even the minimal D "hello world" throws an error at execution.
Speicherzugriffsfehler (Speicherabzug geschrieben) aka. core 
dump


Compiling with ldc2 still works.
Any hint?





d-apt 


After setting ulimit -c unlimited to get the core dumped, I took 
a look with gdb,
to find a hint, now realizing, that it is probably the same 
problem as here:

https://forum.dlang.org/thread/jjaynewwdsyntyehv...@forum.dlang.org?page=1


Re: rdmd main.d leads to Segmentation fault

2018-02-12 Thread Martin Tschierschke via Digitalmars-d-learn

On Sunday, 4 February 2018 at 11:50:05 UTC, Timoses wrote:

On Thursday, 1 February 2018 at 09:01:34 UTC, Kagamin wrote:

On Wednesday, 31 January 2018 at 16:59:15 UTC, Timoses wrote:

And I would need to do what about it?

Sorry, I'm not familiar with assembly code stuff in detail.


You can try to see if it works on another distro or version.


It does work on debian jessie. Stretch failed..


It looks like I have the same issue, I got:
gdb hiworld core
Core was generated by `./hiworld'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x800fbf73 in _d_dso_registry ()

ldc2 is working.

My system: Ubuntu 17.10 32 Bit
4.10.0-37-generic #41-Ubuntu SMP Fri Oct 6 20:20:00 UTC 2017 i686 
i686 i686 GNU/Linux


(No problems on our office system Ubuntu 16.04 64Bit, too)

I tried older DMD (from 2017 and 2016!), because I already used 
DMD on this system, but I got the same same effect.


I am unfamiliar with debugging (gdb etc.) so any hint would be 
appreciated!


Re: No error message in DMD 2.078.2

2018-02-12 Thread psychoticRabbit via Digitalmars-d-learn

On Tuesday, 13 February 2018 at 05:51:05 UTC, Domain wrote:

module main;

void main ()
{
writeln("Hello");
}

Of course, this won't compile, but error message is confused:

C:\Git\hello\source>dmd app.d
app.d(5): Error:
object.Error@(0): Access Violation

0x0065445A
0x006548FE
0x0064DBD3
0x004B0B90
0x004B8A02
0x00594813
0x005797E2
0x77E40608 in RtlAllocateHeap
0x77E3EB5E in RtlAllocateHeap
0x77E2DD5A in RtlRandom
0x004E0F98
0x005B6D16
0x0047BFCA
0x005DD152


erh?

I get a good enough error message(v2.078.2)

Exit code is: 1
..Error: `writeln` is not defined, perhaps `import std.stdio;` is 
needed?


Sounds more like you have env issues.



Re: No error message in DMD 2.078.2

2018-02-12 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, February 13, 2018 05:51:05 Domain via Digitalmars-d-learn wrote:
> module main;
>
> void main ()
> {
>  writeln("Hello");
> }
>
> Of course, this won't compile, but error message is confused:
>
> C:\Git\hello\source>dmd app.d
> app.d(5): Error:
> object.Error@(0): Access Violation
> 
> 0x0065445A
> 0x006548FE
> 0x0064DBD3
> 0x004B0B90
> 0x004B8A02
> 0x00594813
> 0x005797E2
> 0x77E40608 in RtlAllocateHeap
> 0x77E3EB5E in RtlAllocateHeap
> 0x77E2DD5A in RtlRandom
> 0x004E0F98
> 0x005B6D16
> 0x0047BFCA
> 0x005DD152

Report it on bugzilla: https://issues.dlang.org

My guess would be that the printf that's printing the error message is being
given a null string or something along those lines, so it segfaults.

- Jonathan M Davis



No error message in DMD 2.078.2

2018-02-12 Thread Domain via Digitalmars-d-learn

module main;

void main ()
{
writeln("Hello");
}

Of course, this won't compile, but error message is confused:

C:\Git\hello\source>dmd app.d
app.d(5): Error:
object.Error@(0): Access Violation

0x0065445A
0x006548FE
0x0064DBD3
0x004B0B90
0x004B8A02
0x00594813
0x005797E2
0x77E40608 in RtlAllocateHeap
0x77E3EB5E in RtlAllocateHeap
0x77E2DD5A in RtlRandom
0x004E0F98
0x005B6D16
0x0047BFCA
0x005DD152



Re: workspace-d dsymbol Visual Code macOS

2018-02-12 Thread Cody Duncan via Digitalmars-d-learn

On Monday, 12 February 2018 at 14:06:49 UTC, Lucia wrote:

On Tuesday, 6 February 2018 at 21:25:27 UTC, Joel wrote:

[snip]

On Tuesday, 6 February 2018 at 20:59:54 UTC, WebFreak001 wrote:

can you try

git clone https://github.com/Pure-D/workspace-d.git
cd workspace-d
dub upgrade
dub build

and then put the resulting path of the executables in your 
user settings as "d.workspacedPath"


I got the same compile time errors.


Did you manage to solve it? I'm facing the exact same error


I seem to have gotten serve-d to build by modifying the 
dub.selections.json at 
AppData\Roaming\code-d\bin\serve-d\dub.selections.json:

swap "libdparse": "0.8.0-alpha.4",
for "libdparse": "0.7.1",

A quick fetch and build of dsymbol that was successful defaulted 
to using the 0.7.1 libdparse library. That being said, it emits a 
lot of intpromote warnings and a LNK4255.


Re: What should I use for concat string into array in loop?

2018-02-12 Thread Seb via Digitalmars-d-learn

On Tuesday, 13 February 2018 at 01:56:45 UTC, H. S. Teoh wrote:
On Tue, Feb 13, 2018 at 01:58:42AM +, Marc via 
Digitalmars-d-learn wrote:

appender doesn't support string[] so in such case:


Why not? This seems to work:

import std.array;
import std.stdio;
void main() {
auto app = appender!(string[]);
foreach (i; 0 .. 1000) {
app.put("abc");
}
writeln(app.data);
}


T


Or simply don't allocate at all:

---
import std.algorithm, std.range, std.stdio;

void main()
{
"abc".repeat(1000).joiner.writeln;
}
---


https://run.dlang.io/is/ubGZwJ


writeln isn't @nogc atm, but if you want to prove that no 
allocation happens, fallback to printf:



import core.stdc.stdio, std.algorithm, std.range, std.stdio;

void main() @nogc
{
"abc".repeat(1000).each!(s => printf("%.*s", s.length, 
s.ptr));

}
---

https://run.dlang.io/is/V7PWXj


Re: What should I use for concat string into array in loop?

2018-02-12 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, February 12, 2018 17:56:45 H. S. Teoh via Digitalmars-d-learn 
wrote:
> On Tue, Feb 13, 2018 at 01:58:42AM +, Marc via Digitalmars-d-learn 
wrote:
> > appender doesn't support string[] so in such case:
> Why not? This seems to work:
>
>   import std.array;
>   import std.stdio;
>   void main() {
>   auto app = appender!(string[]);
>   foreach (i; 0 .. 1000) {
>   app.put("abc");
>   }
>   writeln(app.data);
>   }

LOL. I read his message too quickly and missed that he had problem with
appender and told him about appender and some alternatives.

I assume that his problem is that he didn't use parens. If he tried
appender!string[], then it's not going to work, because the [] ends up being
associated with the result of appender!string instead of being associated
with string and the passed to appender.

- Jonathan M Davis



Re: What should I use for concat string into array in loop?

2018-02-12 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, February 13, 2018 01:58:42 Marc via Digitalmars-d-learn wrote:
> appender doesn't support string[] so in such case:
> > string[] output;
> > for(...) {
> >
> >if(...) {
> >
> >  output ~= str;
> >
> > }
> >
> > }
>
> Looking for avoid as many immediate allocations as possible, what
> should I use?

Well, the space allocation for dynamic arrays works the same way that it
does with something like vector in C++ or ArrayList in Java. So, it's
amortized constant cost. So, using ~= is just fine.

That being said, every time that ~= is called, the runtime has to check
whether there's room to append in place or whether it has to reallocate the
array. In most cases, if you're appending in a loop, there's going to be
room, but the check isn't necessarily as cheap as would be nice. So, as an
alternative, there's std.array.Appender/appender, which does some of the
checks itself instead of calling the runtime, which speeds it up. So, you
may want to use Appender, but ~= is going to work just fine.

There's also the reserve function for reserving a minimum capacity for the
array, so if you know roughly how much you're going to need, you can call
reserve to tell it to allocate at least that much capacity up front and
reduce the number of allocations - even eliminate them if you really do know
the required capacity up front, since if the capacity is large enough, the
call to reserve will have allocated the necessary memory, and none of the
append calls will actually end up allocating.

- Jonathan M Davis



Re: What should I use for concat string into array in loop?

2018-02-12 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Feb 13, 2018 at 01:58:42AM +, Marc via Digitalmars-d-learn wrote:
> appender doesn't support string[] so in such case:

Why not? This seems to work:

import std.array;
import std.stdio;
void main() {
auto app = appender!(string[]);
foreach (i; 0 .. 1000) {
app.put("abc");
}
writeln(app.data);
}


T

-- 
"You are a very disagreeable person." "NO."


Re: print enum value rather name from enum X : string

2018-02-12 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, February 13, 2018 01:55:59 Marc via Digitalmars-d-learn wrote:
> Thanks for you always well-thought-out answer. I was going to
> print it with writefln() calls more than anywhere else so to
> avoid casts in all those places, which would make it ugly, I just
> used
>
> > enum foo = "a";
> > enum baa = "b";
>
> which I found to be more common D-idiomatic.

Well, those are generally referred to as manifest constants rather than
enums (though the spec calls them anonymous enums), and they're
fundamentally different from enums in the sense that they aren't grouped
together and don't create a type. If all you want is a bunch of constants,
and you're not planning on doing something like having a function take a
variable of an enum type, then it generally makes more sense to use manifest
constants than enums, but if you want to actually treat the enum as a type,
then you need an actual enum. So, really, it comes down to what you're
trying to do.

- Jonathan M Davis



Re: print enum value rather name from enum X : string

2018-02-12 Thread Marc via Digitalmars-d-learn
On Monday, 12 February 2018 at 17:29:47 UTC, Jonathan M Davis 
wrote:
On Monday, February 12, 2018 17:07:50 Marc via 
Digitalmars-d-learn wrote:

[...]


If you actually use the enum values anywhere other than with 
anything from std.conv, std.format, or std.stdio, then when 
they get converted to strings, you get their actual values. 
It's just that those modules specifically grab the names of the 
enum members when converting enums to strings, since in all 
cases other than with strings, it's generally desirable that 
when converting an enum member to string, you get the name - 
and with enums with a base type of string, whether you want the 
name or the value depends on what you're trying to do. Both can 
be useful.


So, when dealing with std.format, std.conv, and std.stdio, if 
you want an enum of base type string to be treated as a string, 
then you'll have to force it with a cast. Anywhere else, if 
they get converted to string, then you'll get their values. If 
that is unacceptable for your use case for whatever reason, 
then you'll have to try a different solution. What solution 
would then work best would presumably depend on whatever it is 
you're actually trying to do.


- Jonathan M Davis


Thanks for you always well-thought-out answer. I was going to 
print it with writefln() calls more than anywhere else so to 
avoid casts in all those places, which would make it ugly, I just 
used



enum foo = "a";
enum baa = "b";


which I found to be more common D-idiomatic.


What should I use for concat string into array in loop?

2018-02-12 Thread Marc via Digitalmars-d-learn

appender doesn't support string[] so in such case:


string[] output;
for(...) {
   if(...) {
 output ~= str;
}
}


Looking for avoid as many immediate allocations as possible, what 
should I use?


Re: inout question

2018-02-12 Thread ketmar via Digitalmars-d-learn

lobo wrote:

sure, i meant that you have to modify the second parameter accordingly. ;-) 
anyway, it's good that you fixed it.


Re: dmd-2.078.2 problems with Ubuntu 17.10 32Bit

2018-02-12 Thread Jordi Sayol via Digitalmars-d-learn
El 12/02/18 a les 21:56, Martin Tschierschke via Digitalmars-d-learn ha escrit:
> I just started to play around with D again on my notebook at home and 
> realized,
> that I have a broken installation.
> Even the minimal D "hello world" throws an error at execution.
> Speicherzugriffsfehler (Speicherabzug geschrieben) aka. core dump
> 
> Compiling with ldc2 still works.
> Any hint?
> 
> 
> 

d-apt 


Re: inout question

2018-02-12 Thread lobo via Digitalmars-d-learn

On Monday, 12 February 2018 at 05:37:23 UTC, ketmar wrote:

Norm wrote:


Hi,

I'm new to D so can someone explain to me what is happening 
here?



void func(const char* s, char** e) {
 import core.stdc.stdlib;
 auto result = strtod(s, e);
}

Error: function core.stdc.stdlib.strtod (scope inout(char)* 
nptr, scope inout(char)** endptr) is not callable using 
argument types (const(char*), char**)


there is a difference between `const char* s`, and 
`const(char)* s`.
the former means that both `s` and `*s` cannot change, the 
latter means that `s` can be changed, but `*s` cannot. i.e. the 
first form means that you cannot do pointer arithmetic with 
`s`, while with second form you can (only *contents* are const, 
not the pointer itself).


that is, `strtod` wants const *contents*, but not pointer. 
`const(char)* s`.


I tried variations of const (char)* s, ... etc. and then stupidly 
realised the problem was with the second parameter 'e'. inout 
does behave the way I expected, I was just looking at the wrong 
parameter.


My silly mistake but thanks for your reply.

Cheers,
Norm



Re: dmd-2.078.2 problems with Ubuntu 17.10 32Bit

2018-02-12 Thread Martin Tschierschke via Digitalmars-d-learn

On Monday, 12 February 2018 at 21:08:30 UTC, Seb wrote:
On Monday, 12 February 2018 at 20:56:11 UTC, Martin 
Tschierschke wrote:
I just started to play around with D again on my notebook at 
home and realized,

that I have a broken installation.
Even the minimal D "hello world" throws an error at execution.
Speicherzugriffsfehler (Speicherabzug geschrieben) aka. core 
dump


Compiling with ldc2 still works.
Any hint?


How did you install DMD? It's probably related to this.
I recommend using the official releases:

curl https://dlang.org/install.sh | bash -s dmd


See also: https://dlang.org/install.html


I did so, and after that, I tried to install via dpkg -i *.deb, 
than I tried to use an older version... without success, maybe I 
first have to clean up? But how to deinstall best?


Re: dmd-2.078.2 problems with Ubuntu 17.10 32Bit

2018-02-12 Thread Seb via Digitalmars-d-learn
On Monday, 12 February 2018 at 20:56:11 UTC, Martin Tschierschke 
wrote:
I just started to play around with D again on my notebook at 
home and realized,

that I have a broken installation.
Even the minimal D "hello world" throws an error at execution.
Speicherzugriffsfehler (Speicherabzug geschrieben) aka. core 
dump


Compiling with ldc2 still works.
Any hint?


How did you install DMD? It's probably related to this.
I recommend using the official releases:

curl https://dlang.org/install.sh | bash -s dmd


See also: https://dlang.org/install.html


dmd-2.078.2 problems with Ubuntu 17.10 32Bit

2018-02-12 Thread Martin Tschierschke via Digitalmars-d-learn
I just started to play around with D again on my notebook at home 
and realized,

that I have a broken installation.
Even the minimal D "hello world" throws an error at execution.
Speicherzugriffsfehler (Speicherabzug geschrieben) aka. core dump

Compiling with ldc2 still works.
Any hint?




Re: print enum value rather name from enum X : string

2018-02-12 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, February 12, 2018 17:07:50 Marc via Digitalmars-d-learn wrote:
> If I have an enum like this:
> > enum S  : string {
> >
> > foo = "a",
> > baa = "b"
> >
> >}
>
> when I printed it, to my surprise I get the enum field name
>
> rather value:
> > writefln("%s v%s", S.foo, S.baa);
>
> output:
> > foo vbaa
>
> instead of
>
> > a vb
>
> a cast solves it but without cast everywhere I need that enum
> member, is there any other way to do it? otherwise I'll have to
> switch to a class with static immutable strings, right?

If you actually use the enum values anywhere other than with anything from
std.conv, std.format, or std.stdio, then when they get converted to strings,
you get their actual values. It's just that those modules specifically grab
the names of the enum members when converting enums to strings, since in all
cases other than with strings, it's generally desirable that when converting
an enum member to string, you get the name - and with enums with a base type
of string, whether you want the name or the value depends on what you're
trying to do. Both can be useful.

So, when dealing with std.format, std.conv, and std.stdio, if you want an
enum of base type string to be treated as a string, then you'll have to
force it with a cast. Anywhere else, if they get converted to string, then
you'll get their values. If that is unacceptable for your use case for
whatever reason, then you'll have to try a different solution. What solution
would then work best would presumably depend on whatever it is you're
actually trying to do.

- Jonathan M Davis



print enum value rather name from enum X : string

2018-02-12 Thread Marc via Digitalmars-d-learn

If I have an enum like this:


enum S  : string {
foo = "a",
baa = "b"
}


when I printed it, to my surprise I get the enum field name 
rather value:



writefln("%s v%s", S.foo, S.baa); 


output:


foo vbaa


instead of


a vb


a cast solves it but without cast everywhere I need that enum 
member, is there any other way to do it? otherwise I'll have to 
switch to a class with static immutable strings, right?




Re: How does this error from dub mean "dlang Non-selected Y package is available with version X"?

2018-02-12 Thread Marc via Digitalmars-d-learn

On Monday, 12 February 2018 at 15:51:58 UTC, Marc wrote:

the warning is:


Non-selected package lnk is available with version ~>0.2.1.


What does it mean by *Non-selected* package lnk is available?
from what I could tell from the page, it's highest version.
But I've tried low versions anyway to see if it Works 0.2.0, 
0.1.1 etc and none did.


I noticied I put "lnk": "~>0.2.1" on cachedUpgrades section so 
I moved there to just created "dependencies" section then the 
dub's error is gone but it fail to find the lnk library:



Error: module lnk is in file 'lnk.d' which cannot be read


some info:

The package I'm trying to include is: 
https://code.dlang.org/packages/lnk

DUB version 1.5.0, built on Sep  1 2017
DMD32 D Compiler v2.076.0
Windows 10/64bit

What am I missing? I'm new to dub so everything is new to me, 
by now.


so I find the issue. I'm ashamed to say: I was editing the 
dub.json inside the dub folder not the one in the my 
application's root.





Re: How does this error from dub mean "dlang Non-selected Y package is available with version X"?

2018-02-12 Thread Seb via Digitalmars-d-learn

On Monday, 12 February 2018 at 15:51:58 UTC, Marc wrote:

the warning is:


Non-selected package lnk is available with version ~>0.2.1.


What does it mean by *Non-selected* package lnk is available?
from what I could tell from the page, it's highest version.
But I've tried low versions anyway to see if it Works 0.2.0, 
0.1.1 etc and none did.


I noticied I put "lnk": "~>0.2.1" on cachedUpgrades section so 
I moved there to just created "dependencies" section then the 
dub's error is gone but it fail to find the lnk library:



Error: module lnk is in file 'lnk.d' which cannot be read


some info:

The package I'm trying to include is: 
https://code.dlang.org/packages/lnk

DUB version 1.5.0, built on Sep  1 2017
DMD32 D Compiler v2.076.0
Windows 10/64bit

What am I missing? I'm new to dub so everything is new to me, 
by now.


1) What's your dub.sdl / dub.json?
2) Did you try dub upgrade?


How does this error from dub mean "dlang Non-selected Y package is available with version X"?

2018-02-12 Thread Marc via Digitalmars-d-learn

the warning is:


Non-selected package lnk is available with version ~>0.2.1.


What does it mean by *Non-selected* package lnk is available?
from what I could tell from the page, it's highest version.
But I've tried low versions anyway to see if it Works 0.2.0, 
0.1.1 etc and none did.


I noticied I put "lnk": "~>0.2.1" on cachedUpgrades section so I 
moved there to just created "dependencies" section then the dub's 
error is gone but it fail to find the lnk library:



Error: module lnk is in file 'lnk.d' which cannot be read


some info:

The package I'm trying to include is: 
https://code.dlang.org/packages/lnk

DUB version 1.5.0, built on Sep  1 2017
DMD32 D Compiler v2.076.0
Windows 10/64bit

What am I missing? I'm new to dub so everything is new to me, by 
now.


Re: opCast cannot implicitly convert a.opCast of type X to Y

2018-02-12 Thread rumbu via Digitalmars-d-learn

On Monday, 12 February 2018 at 02:05:16 UTC, aliak wrote:
From spec: Cast expression: "cast ( Type ) UnaryExpression" 
converts UnaryExpresssion to Type.


And https://dlang.org/spec/operatoroverloading.html#cast makes 
no mention of the return type of opCast. One could think that 
the return type of opCast would be the return type. But it 
seems it must be the same as the template parameter of opCast 
else you get a compile error that seems like it can be much 
better.


- Ali


In my opinion, you should fill a documentation enhancement 
request on issues.dlang.org.


Re: workspace-d dsymbol Visual Code macOS

2018-02-12 Thread Lucia via Digitalmars-d-learn

On Tuesday, 6 February 2018 at 21:25:27 UTC, Joel wrote:

[snip]

On Tuesday, 6 February 2018 at 20:59:54 UTC, WebFreak001 wrote:

can you try

git clone https://github.com/Pure-D/workspace-d.git
cd workspace-d
dub upgrade
dub build

and then put the resulting path of the executables in your 
user settings as "d.workspacedPath"


I got the same compile time errors.


Did you manage to solve it? I'm facing the exact same error



Re: typedef behavior

2018-02-12 Thread Alex via Digitalmars-d-learn

On Monday, 12 February 2018 at 11:25:40 UTC, Simen Kjærås wrote:
I'm sorry, I was apparently unclear. When I said 'static array' 
above, I meant 'static member'.


Since we've been using arrays in our examples, there could be 
conflation of ideas there. The fact that you can access (and 
even modify) the static member's .ptr property (as in S.arr.ptr 
= [1,2,3].ptr), doesn't mean you can change the address of the 
array itself (the static data in S). This can be shown by 
writeln(), which will not change.


When you call a static method, as the one in this example:

struct S {
static int[] arr;
static void foo() { arr[0]++; }
}

unittest {
S.foo();
}

No pointer is being passed to foo - it's exactly equivalent to 
this code:


module test;
int[] arr;


/*
yeah... just saw it in the AST-output. However, even if this is 
rewrited, I cannot reference to the arr as

.arr
I have to write
S.arr
*/


void foo() { arr[0]++; }

unittest {
foo();
}

Likewise, when a non-static method modifies a static member, it 
doesn't need to look up the address of the static member - its 
address is hard-coded.


As an example, try this:

struct S {
   static int n1;
   int n2;
}

unittest {
import std.stdio;
S s1;
S s2;
// These should be equal:
writeln();
writeln();


// sure, this is because the type of s1 and s2 is the same.


// These should be different:
writeln();
writeln();
}

--
  Simen


It is even worse, then I thought. Let us simplify our examples a 
little bit:


/// --- code --- ///
import std.typecons;

struct S { static int i; }
alias T = Typedef!S;
struct U { static int i; }

static assert(is(typeof(S.i) == int));
static assert(is(typeof(T.i) == void));

void main()
{
S.i = 42;
assert(U.i != S.i);
}
/// --- code ends --- ///

So... I'm starting to see your point now, I think.

What I expected from the Typedef was an ability to "templatify" a 
type ad-hoc. I wanted to say, well, I have a dedicated type and 
some different manifestations of it which I define by a Typedef.
After that, I could write some functions for different Typedefs 
being sure, that only the right types would be addressed by the 
functions, as specified in the example of Typedef.


However, as I can see, the definition of "static" takes advantage 
and heaves the according member away. Not only away from 
instances, but also from types (which is yeah... well... lets 
call it unexpected :) )


However, if I define another type manually, this is not the case.
So, static behaves differently on Typedefs, then on different 
types, defined manually.


Re: typedef behavior

2018-02-12 Thread Simen Kjærås via Digitalmars-d-learn

On Monday, 12 February 2018 at 09:58:13 UTC, Alex wrote:

On Monday, 12 February 2018 at 09:37:56 UTC, Simen Kjærås wrote:


Not really, since D doesn't have a concept of an address 
associated with a type, only with instances of it. So when you 
use a static array, the address is hard-coded.


--
  Simen


Ok... so the query on ptr on a static is not to be allowed? And 
the fact I can perform it is a bug?


I'm sorry, I was apparently unclear. When I said 'static array' 
above, I meant 'static member'.


Since we've been using arrays in our examples, there could be 
conflation of ideas there. The fact that you can access (and even 
modify) the static member's .ptr property (as in S.arr.ptr = 
[1,2,3].ptr), doesn't mean you can change the address of the 
array itself (the static data in S). This can be shown by 
writeln(), which will not change.


When you call a static method, as the one in this example:

struct S {
static int[] arr;
static void foo() { arr[0]++; }
}

unittest {
S.foo();
}

No pointer is being passed to foo - it's exactly equivalent to 
this code:


module test;
int[] arr;
void foo() { arr[0]++; }

unittest {
foo();
}

Likewise, when a non-static method modifies a static member, it 
doesn't need to look up the address of the static member - its 
address is hard-coded.


As an example, try this:

struct S {
   static int n1;
   int n2;
}

unittest {
import std.stdio;
S s1;
S s2;
// These should be equal:
writeln();
writeln();
// These should be different:
writeln();
writeln();
}

--
  Simen


Re: inout question

2018-02-12 Thread Kagamin via Digitalmars-d-learn

On Monday, 12 February 2018 at 05:33:16 UTC, Norm wrote:
I thought inout was supposed to take const or non-const 
variants, so expected the original const char* s to work.


The problem is in argument e: it's mutable, and strtod stores 
there a part of s, if s is const you end up with const data 
available for writing through e. Should be const(char)** e.


Re: typedef behavior

2018-02-12 Thread Alex via Digitalmars-d-learn

On Monday, 12 February 2018 at 09:37:56 UTC, Simen Kjærås wrote:


Not really, since D doesn't have a concept of an address 
associated with a type, only with instances of it. So when you 
use a static array, the address is hard-coded.


--
  Simen


Ok... so the query on ptr on a static is not to be allowed? And 
the fact I can perform it is a bug?


Re: typedef behavior

2018-02-12 Thread Simen Kjærås via Digitalmars-d-learn

On Monday, 12 February 2018 at 09:10:52 UTC, Alex wrote:

A more extreme example: You have a compiled library, and some 
.di (header) files. In one of those files is this code:


struct S {
static int[] arr;
void foo();
}

Now how should Typedef go about making foo() do the right 
thing? Even with compiler support, this is impossible - the 
source of S.foo is simply not available, and it doesn't take 
the address of the static data as a parameter anywhere.


But isn't foo scoped somehow?
I mean, if foo is part of a type, then either you have to write 
s.foo, or S.foo. And if the address of a static belongs to a 
type, shouldn't this resolve the ambiguities?


Not really, since D doesn't have a concept of an address 
associated with a type, only with instances of it. So when you 
use a static array, the address is hard-coded.


--
  Simen


Re: typedef behavior

2018-02-12 Thread Alex via Digitalmars-d-learn

On Monday, 12 February 2018 at 08:51:14 UTC, Simen Kjærås wrote:
I agree that'd be nice. Sadly, it's not a reasonable 
expectation. :(


:)

A more extreme example: You have a compiled library, and some 
.di (header) files. In one of those files is this code:


struct S {
static int[] arr;
void foo();
}

Now how should Typedef go about making foo() do the right 
thing? Even with compiler support, this is impossible - the 
source of S.foo is simply not available, and it doesn't take 
the address of the static data as a parameter anywhere.


--
  Simen


But isn't foo scoped somehow?
I mean, if foo is part of a type, then either you have to write 
s.foo, or S.foo. And if the address of a static belongs to a 
type, shouldn't this resolve the ambiguities?


Re: What does "(this This)" mean in member function templates?

2018-02-12 Thread Nathan S. via Digitalmars-d-learn
On Monday, 12 February 2018 at 08:42:42 UTC, rikki cattermole 
wrote:

https://dlang.org/spec/template.html#TemplateThisParameter


Cheers.


Re: typedef behavior

2018-02-12 Thread Simen Kjærås via Digitalmars-d-learn

On Sunday, 11 February 2018 at 19:33:23 UTC, Alex wrote:

On Sunday, 11 February 2018 at 15:18:11 UTC, Simen Kjærås wrote:


Basically, Typedef looks like this:

struct Typedef(T) {
T _payload;
// Forward method calls, member access, etc, to _payload.
}

If T looks like this:

struct T {
static int[3] arr;
void foo() { arr[0]++; }
}

How is Typedef supposed to wrap T.foo in such a way that it 
uses a different arr depending on whether it's called from the 
Typedef or from T?


--
  Simen


In the same way as it is handled by this:

/// --- code --- ///

void main(){}

static assert(T.arr.ptr != S.arr.ptr);

struct T {
static int[3] arr;
void foo() { arr[0]++; }
}

struct S {
static int[3] arr;
void foo() { arr[0]++; }
}

/// --- code ends --- ///

I understand that Typedef should be kept simple. But if it 
defines a type which is recognized as another type in respect 
to the underlying one, then I should be able to rely on 
independence of everything, like I would copy/paste the 
implementation. Or do I misinterpret something?


I agree that'd be nice. Sadly, it's not a reasonable expectation. 
:(


A more extreme example: You have a compiled library, and some .di 
(header) files. In one of those files is this code:


struct S {
static int[] arr;
void foo();
}

Now how should Typedef go about making foo() do the right thing? 
Even with compiler support, this is impossible - the source of 
S.foo is simply not available, and it doesn't take the address of 
the static data as a parameter anywhere.


--
  Simen


Re: What does "(this This)" mean in member function templates?

2018-02-12 Thread Simen Kjærås via Digitalmars-d-learn

On Monday, 12 February 2018 at 08:35:05 UTC, Nathan S. wrote:

For example in std.container.rbtree:

---
auto equalRange(this This)(Elem e)
{
auto beg = _firstGreaterEqual(e);
alias RangeType = RBRange!(typeof(beg));
if (beg is _end || _less(e, beg.value))
// no values are equal
return RangeType(beg, beg);
static if (allowDuplicates)
{
return RangeType(beg, _firstGreater(e));
}
else
{
// no sense in doing a full search, no duplicates 
are allowed,

// so we just get the next node.
return RangeType(beg, beg.next);
}
}
---


It's a template this parameter:
https://dlang.org/spec/template.html#template_this_parameter

Simply put, it gets the type of the 'this' parameter when the 
function is invoked, with all type modifiers. For a class A with 
a subclass B, 'This' would be B if called from B, and const(A) 
when called from const(A).


The type of the 'this' parameter is the statically known type, 
not the dynamic type. This creates some limitations, as shown 
below.


Some examples:

struct S {
   void foo(this This)() {
   writeln(This.stringof);
   }
}

class A {
void foo(this This)() {
writeln(This.stringof);
}
void bar() {
foo();
}
}

class B : A{}

unittest {
S s;
const shared S css;
immutable S iss;
s.foo(); // S
css.foo(); // shared(const(S))
iss.foo(); // immutable(S)
B b = new B();
A a = b;
b.foo(); // B
a.foo(); // A, since typeof(a) == A.
b.bar(); // A, since bar() calls foo() in a context where the 
type of 'this' is A.

}

--
  Simen


Re: Understanding the AST...

2018-02-12 Thread RazvanN via Digitalmars-d-learn

Hi Joe,

I suggest you watch this video which explains how the parse time 
visitors work: https://www.youtube.com/watch?v=tK072jcoWv4 .


On Tuesday, 6 February 2018 at 12:03:06 UTC, joe wrote:

Hello everybody!

Last week end I found this post ( 
https://dlang.org/blog/2017/08/01/a-dub-case-study-compiling-dmd-as-a-library/ ) on the Blog and thought to myself awesome.


So I built the library and everything went smooth. Thanks for 
the effort of all the involved people who made that possible!


I've had a look at the 2 examples, too, the avg. function lines 
( https://github.com/dlang/dmd/blob/master/src/examples/avg.d ) 
and the import ( 
https://github.com/dlang/dmd/blob/master/src/examples/impvisitor.d ) ones and for a start I decided to make a program that prints the outline of a module.


Turns out I don't really understand how to access the data in 
the AST.
For everything there's a visitor method and overriding a few of 
them to print return statements and some such works as 
advertised.


However, I have no idea where I am in the tree when any of 
those methods are called.
Like for example in 
FunctionLengthVisitor(AST).visitFuncBody(AST.FuncDeclaration 
fd).
I have a function declaration object which tells me everything 
about what's inside the function, but how do I know what or 
where this function belongs to, where can I get that 
information ? I don't see anything about UDAs either, nor the 
doc comment.




The FuncDeclaration node contains all the information for that.
For example, you can access fd.parent to see if the function is
declared at top-level (in which case, the parent is going to be a 
module
declaration ) or if it is a nested function (in a class, in a 
struct, in a function).
Every AST node contains information about the position in the 
AST, all you
have to do is find how to get that information: which field to 
access or which

member function to call.

I understand when visitor.getAvgLen is called with the parsed 
module, the accept function calls a visitor overload for each 
member.
But this sounds to me like I'd have to do a lot of book keeping 
in my visitor to keep track of things which are already present 
in the AST.


The function average length visitor inherits a transitive visitor
which means that the AST traversal logic is already implemented 
for you.
All you have to do is override the visiting methods of interest 
and do
whatever suits you : print stuff, alter the ast, stop the 
visitation or

continue the visitation (by calling super.visit(ASTnode)).



Any insight to this would be much appreciated :)


I know that my explanations might not be very explicit, but if 
you have an example please post it and we can work on it.


Cheers,
RazvanN



Re: What does "(this This)" mean in member function templates?

2018-02-12 Thread rikki cattermole via Digitalmars-d-learn

On 12/02/2018 8:35 AM, Nathan S. wrote:

For example in std.container.rbtree:

---
     auto equalRange(this This)(Elem e)
     {
     auto beg = _firstGreaterEqual(e);
     alias RangeType = RBRange!(typeof(beg));
     if (beg is _end || _less(e, beg.value))
     // no values are equal
     return RangeType(beg, beg);
     static if (allowDuplicates)
     {
     return RangeType(beg, _firstGreater(e));
     }
     else
     {
     // no sense in doing a full search, no duplicates are allowed,
     // so we just get the next node.
     return RangeType(beg, beg.next);
     }
     }
---


https://dlang.org/spec/template.html#TemplateThisParameter


What does "(this This)" mean in member function templates?

2018-02-12 Thread Nathan S. via Digitalmars-d-learn

For example in std.container.rbtree:

---
auto equalRange(this This)(Elem e)
{
auto beg = _firstGreaterEqual(e);
alias RangeType = RBRange!(typeof(beg));
if (beg is _end || _less(e, beg.value))
// no values are equal
return RangeType(beg, beg);
static if (allowDuplicates)
{
return RangeType(beg, _firstGreater(e));
}
else
{
// no sense in doing a full search, no duplicates are 
allowed,

// so we just get the next node.
return RangeType(beg, beg.next);
}
}
---


Re: opUnary with ++ and -- on a struct that has a dynamic array

2018-02-12 Thread aliak via Digitalmars-d-learn

On Monday, 12 February 2018 at 06:16:21 UTC, rumbu wrote:

writeln(a++) translates to:

A copy = a;
a.opUnary!"++";
writeln(copy);

copy.a[] and a.a[] are the same reference, you increment 
a.a[0]/copy.a[0] in opUnary


to make this work you will need a postblit constructor:

struct A
{
   
   this(this)
   {
 a = a.dup; //make a copy a;
   }
}

In fact, you'll find exactly the same scenario in docs: 
https://dlang.org/spec/struct.html#struct-postblit




Ah! Awesome. Yes that works, thank you!

Cheers