Re: Real simple unresolved external symbols question...

2021-02-10 Thread kinke via Digitalmars-d-learn

On Thursday, 11 February 2021 at 00:18:23 UTC, H. S. Teoh wrote:
On Wed, Feb 10, 2021 at 11:35:27PM +, WhatMeWorry via 
Digitalmars-d-learn wrote: [...]

Okay, thanks. Then why does the README.md at

https://github.com/dlang/druntime

say "Runtime is typically linked together with Phobos in a 
release such that the compiler only has to link to a single 
library to provide the user with the runtime and the standard 
library."


Probably outdated information.  Somebody should submit a PR for 
it. ;-)


It basically says there's no separate libdruntime with DMD, it's 
included in libphobos2 (unlike LDC). So 'runtime' in the context 
of the druntime repo is 'druntime', not 'C runtime and other 
platform libs' libphobos/druntime depend on.




Re: Real simple unresolved external symbols question...

2021-02-10 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Feb 10, 2021 at 11:35:27PM +, WhatMeWorry via Digitalmars-d-learn 
wrote:
[...]
> Okay, thanks. Then why does the README.md at
> 
> https://github.com/dlang/druntime
> 
> say "Runtime is typically linked together with Phobos in a release
> such that the compiler only has to link to a single library to provide
> the user with the runtime and the standard library."

Probably outdated information.  Somebody should submit a PR for it. ;-)


T

-- 
Let X be the set not defined by this sentence...


Re: Real simple unresolved external symbols question...

2021-02-10 Thread kinke via Digitalmars-d-learn

On Tuesday, 9 February 2021 at 19:37:17 UTC, WhatMeWorry wrote:


I'm trying to create a super simple dynamic library consisting 
of two files:



  file2.d --
extern(D):
double addEight(double d) { return (d + 8.0); }

 fileB.d --
extern(D)
{
string concatSuffix(string s) { return (s ~ ".ext"); }
}



dmd -m64 -c file2.d
dmd -m64 -c fileB.d

creates file2.obj and fileB.obj files

link.exe /DLL /NOENTRY file2.obj fileB.obj msvcrt.lib


If you go the easy route and use LDC, everything works:

ldc2 -shared file1.d file2.d
=> file1.dll

Or, if you really prefer separate compile + link:

ldc2 -c file1.d
ldc2 -c file2.d
ldc2 -shared file1.obj file2.obj

Use `-v` to see what the actual link.exe cmdline is, and notice 
the MSVC and Windows libs that are implicitly added. - IIRC, DMD 
only embeds these system libs into the object file containing 
main/DllMain (and you have none), whereas LDC adds them to the 
linker cmdline.


Re: Profiling

2021-02-10 Thread mw via Digitalmars-d-learn

On Wednesday, 10 February 2021 at 11:52:51 UTC, JG wrote:


As a follow up question I would like to know what tool people 
use to profile d programs?


I use this one:

https://code.dlang.org/packages/profdump

e.g.

```
dub build --build=debug --build=profile

# run your program to generate trace.log

profdump -b trace.log trace.log.b
profdump -f --dot --threshold 1 trace.log trace.log.dot
echo 'view it with: xdot trace.log.dot'
```



Re: Real simple unresolved external symbols question...

2021-02-10 Thread WhatMeWorry via Digitalmars-d-learn
On Wednesday, 10 February 2021 at 11:38:00 UTC, Ferhat Kurtulmuş 
wrote:

On Tuesday, 9 February 2021 at 19:37:17 UTC, WhatMeWorry wrote:


I'm trying to create a super simple dynamic library consisting 
of two files:


[...]


remove /NOENTRY, and include "mixin SimpleDllMain;" in one of 
the sources. And link with druntime.


link /DLL file2.obj fileB.obj druntime-ldc.lib msvcrt.lib



Okay, thanks. Then why does the README.md at

https://github.com/dlang/druntime

say "Runtime is typically linked together with Phobos in a 
release such that the compiler only has to link to a single 
library to provide the user with the runtime and the standard 
library."


Re: Profiling

2021-02-10 Thread Max Haughton via Digitalmars-d-learn
On Wednesday, 10 February 2021 at 13:31:09 UTC, Guillaume Piolat 
wrote:

On Wednesday, 10 February 2021 at 11:52:51 UTC, JG wrote:

[...]


Here is what I use for sampling profiler:

(On Windows)

Build with LDC, x86_64, with dub -b release-debug in order to 
have debug info.

Run your program into:
- Intel Amplifier (free with System Studio)
- AMD CodeXL (more lightweight, and very good)
- Very Sleepy

(On Mac)

Build with dub -b release-debug
Run your program with Instruments.app which you can find in 
your Xcode.app


(On Linux)
I don't know.


Though most of the time to validate the optimization a 
comparison program that runs two siilar programs and computer 
the speed difference can be needed.


All Intel tools I'm aware of support (and are free on) Linux. 
Also, it's just called vTune now and it's been put under the 
"oneAPI" banner.


Re: GC.addRange in pure function

2021-02-10 Thread Petar via Digitalmars-d-learn
On Wednesday, 10 February 2021 at 16:25:44 UTC, Petar Kirov 
[ZombineDev] wrote:

[..]


A few practical examples:

Here it is deemed that the only observable side-effect of 
`malloc` and friends is the setting of `errno` in case of 
failure, so these wrappers ensure that this is not observed. 
Surely there are low-level ways to observe it (and also the act 
of allocating / deallocating memory on the C heap), but this 
definition purity what the standard library has decided it was 
reasonable:

https://github.com/dlang/druntime/blob/master/src/core/memory.d#L1082-L1150

These two function calls in Array.~this() can be marked as 
`pure`, as the Array type as a whole implements the RAII design 
pattern and offers at least basic exception-safety guarantees:

https://github.com/dlang/phobos/blob/81a968dee68728f7ea245b6983eb7236fb3b2981/std/container/array.d#L296-L298

(The whole function is not marked pure, as the purity depends on 
the purity of the destructor of the template type parameter `T`.)




Re: GC.addRange in pure function

2021-02-10 Thread Petar via Digitalmars-d-learn

On Wednesday, 10 February 2021 at 13:44:53 UTC, vit wrote:

On Wednesday, 10 February 2021 at 12:17:43 UTC, rm wrote:

On 09/02/2021 5:05, frame wrote:

On Sunday, 7 February 2021 at 14:13:18 UTC, vitamin wrote:
Why using 'new' is allowed in pure functions but calling 
GC.addRange or GC.removeRange isn't allowed?


Does 'new' violate the 'pure' paradigm? Pure functions can 
only call pure functions and GC.addRange or GC.removeRange is 
only 'nothrow @nogc'.


new allocates memory via the GC and the GC knows to scan this 
location. Seems like implicit GC.addRange.


Yes, this is my problem, if `new` can create object in pure 
function, then GC.addRange and GC.removeRange is may be pure 
too.


Can I call GC.addRange and GC.removeRange from pure function 
without problem? (using assumePure(...)() ).


TL;DR Yes, you can, but it depends on what "without problem" 
means for you :P



# The Dark Arts of practical D code
===

According to D's general approach to purity, malloc/free/GC.* are 
indeed impure as they read and write global **mutable** state, 
but are still allowed in pure functions **if encapsulated 
properly**. The encapsulation is done by @trusted wrappers which 
must be carefully audited by humans - the compiler can't help you 
with that.


The general rule that you must follow for such 
*callable-from-pure* code (technically it is labeled as `pure`, 
e.g.:


pragma(mangle, "malloc") pure @system @nogc nothrow
void* fakePureMalloc(size_t);

but I prefer to make the conceptual distinction) is that the 
effect of calling the @trusted wrapper must not drastically leak 
/ be observed.


What "drastically" means depends on what you want `pure` to mean 
in your application. Which side-effects you want to protect 
against by using `pure`? It is really a high-level concern that 
you as a developer must decide on when writing/using @trusted 
pure code in your program. For example, generally everyone will 
agree that network calls are impure. But what about logging? It's 
impure by definition, since it mutates a global log stream. But 
is this effect worth caring about? In some specific situations it 
maybe ok to ignore. This is why in D you can call `writeln` in 
`pure` functions, as long as it's inside a `debug` block. But 
given that you as a developer can decide whether to pass `-debug` 
option to the compiler, essentially you're in control of what 
`pure` means for your codebase, at least to some extent.


100% mathematical purity is impossible even in the most strict 
functional programming language implementations, since our 
programs run on actual hardware and not on an idealized 
mathematical machine. For example, even the act of reading 
immutable data can be globally observed as by measuring the 
memory access times - see Spectre [1] and all other 
microarchitecture side-channel [1] vulnerabilities.


[1]: 
https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)

[2]: https://en.wikipedia.org/wiki/Side-channel_attack

That said, function purity is not useless at all, quite the 
contrary. It is about making your programs more deterministic and 
easy to reason about. We all want less bugs in our code and less 
time spent chasing hard to reproduce crashes, right?


`pure` is really about limiting, containing / compartmentalizing 
and controlling the the (in-deterministic) global effects in your 
program. Ideally you should strive to structure your programs as 
a pure core, driven by an imperative, impure shell. E.g. if 
you're working on an accounting application, the core is the part 
that implements the main domain / business logic and should be 
100% deterministic and pure. The imperative shell is the part 
that reads spreadsheet files, exports to pdf, etc. (actually just 
the actual file I/O needs to be impure - the actual decoding / 
encoding of data structures can be perfectly pure).



Now, back to practice and the question of memory management.

Of course allocating memory is globally observable effect and 
even locally one can compare pointers, as Paul Backus mentioned, 
as D is a systems language. However, as a practical concession, 
D's concept of pure-ity is about ensuring high-level invariants 
and so such low-level concerns can be ignored, as long as the 
codebase doesn't observe them. What does it mean to observe them? 
Here's an example:


---
void main()
{
import std.stdio : writeln;
observingLowLevelSideEffects.writeln; // `false`, but could 
be `true`

notObservingSideEffects.writeln; // always `true`
}

// BAD:
bool observingLowLevelSideEffects() pure
{
immutable a = [2];
immutable b = [2];
return a.ptr == b.ptr;
}

// OK
bool notObservingSideEffects() pure
{
immutable a = [2];
immutable b = [2];
return a == b;
}
---

`observingLowLevelSideEffects` is bad, as according to the 
language rules, the compiler is free to make `a` and `b` point to 
the same immutable array, the result of the function 

Re: GC.addRange in pure function

2021-02-10 Thread vit via Digitalmars-d-learn

On Wednesday, 10 February 2021 at 12:17:43 UTC, rm wrote:

On 09/02/2021 5:05, frame wrote:

On Sunday, 7 February 2021 at 14:13:18 UTC, vitamin wrote:
Why using 'new' is allowed in pure functions but calling 
GC.addRange or GC.removeRange isn't allowed?


Does 'new' violate the 'pure' paradigm? Pure functions can 
only call pure functions and GC.addRange or GC.removeRange is 
only 'nothrow @nogc'.


new allocates memory via the GC and the GC knows to scan this 
location. Seems like implicit GC.addRange.


Yes, this is my problem, if `new` can create object in pure 
function, then GC.addRange and GC.removeRange is may be pure too.


Can I call GC.addRange and GC.removeRange from pure function 
without problem? (using assumePure(...)() ).


Re: Profiling

2021-02-10 Thread Guillaume Piolat via Digitalmars-d-learn

On Wednesday, 10 February 2021 at 11:52:51 UTC, JG wrote:


Thanks for the suggestions. However, I would prefer not to 
spend time trying to debug d-profile-viewer at the moment.


As a follow up question I would like to know what tool people 
use to profile d programs?


Here is what I use for sampling profiler:

(On Windows)

Build with LDC, x86_64, with dub -b release-debug in order to 
have debug info.

Run your program into:
- Intel Amplifier (free with System Studio)
- AMD CodeXL (more lightweight, and very good)
- Very Sleepy

(On Mac)

Build with dub -b release-debug
Run your program with Instruments.app which you can find in your 
Xcode.app


(On Linux)
I don't know.


Though most of the time to validate the optimization a comparison 
program that runs two siilar programs and computer the speed 
difference can be needed.


Re: Profiling

2021-02-10 Thread drug via Digitalmars-d-learn

On 2/10/21 2:52 PM, JG wrote:

On Tuesday, 9 February 2021 at 18:33:16 UTC, drug wrote:

On Tuesday, 9 February 2021 at 07:45:13 UTC, JG wrote:
I was trying to profile a d program. So I ran: dub build 
--build=profile. I then ran the program and it produced trace.log and 
trace.def. I then ran d-profile-viewer and got the following error:


std.conv.ConvException@/home/jg/dlang/ldc-1.24.0/bin/../import/std/conv.d(2382): 
Unexpected '-' when converting from type char[] to type ulong


I'm guessing only but it looks like slurp is used to read text output 
but the format used does not correspond to the real data format.


Thanks for the suggestions. However, I would prefer not to spend time 
trying to debug d-profile-viewer at the moment.


As a follow up question I would like to know what tool people use to 
profile d programs?


Could you provide trace.log that I can take a look? I have no much time 
but some bugs can be fixed fast. It would be ideal if you create the 
issue in the package repo and provides the test case. Also there is 
probability the author will fix this.


Re: GC.addRange in pure function

2021-02-10 Thread rm via Digitalmars-d-learn

On 09/02/2021 5:05, frame wrote:

On Sunday, 7 February 2021 at 14:13:18 UTC, vitamin wrote:
Why using 'new' is allowed in pure functions but calling GC.addRange 
or GC.removeRange isn't allowed?


Does 'new' violate the 'pure' paradigm? Pure functions can only call 
pure functions and GC.addRange or GC.removeRange is only 'nothrow @nogc'.


new allocates memory via the GC and the GC knows to scan this location. 
Seems like implicit GC.addRange.


Re: Profiling

2021-02-10 Thread JG via Digitalmars-d-learn

On Tuesday, 9 February 2021 at 18:33:16 UTC, drug wrote:

On Tuesday, 9 February 2021 at 07:45:13 UTC, JG wrote:
I was trying to profile a d program. So I ran: dub build 
--build=profile. I then ran the program and it produced 
trace.log and trace.def. I then ran d-profile-viewer and got 
the following error:


std.conv.ConvException@/home/jg/dlang/ldc-1.24.0/bin/../import/std/conv.d(2382):
 Unexpected '-' when converting from type char[] to type ulong


I'm guessing only but it looks like slurp is used to read text 
output but the format used does not correspond to the real data 
format.


Thanks for the suggestions. However, I would prefer not to spend 
time trying to debug d-profile-viewer at the moment.


As a follow up question I would like to know what tool people use 
to profile d programs?


Re: Real simple unresolved external symbols question...

2021-02-10 Thread Ferhat Kurtulmuş via Digitalmars-d-learn

On Tuesday, 9 February 2021 at 19:37:17 UTC, WhatMeWorry wrote:


I'm trying to create a super simple dynamic library consisting 
of two files:


[...]


remove /NOENTRY, and include "mixin SimpleDllMain;" in one of the 
sources. And link with druntime.


link /DLL file2.obj fileB.obj druntime-ldc.lib msvcrt.lib


Re: Real simple unresolved external symbols question...

2021-02-10 Thread Rumbu via Digitalmars-d-learn

On Tuesday, 9 February 2021 at 19:37:17 UTC, WhatMeWorry wrote:


I'm trying to create a super simple dynamic library consisting 
of two files:



  file2.d --
extern(D):
double addEight(double d) { return (d + 8.0); }

 fileB.d --
extern(D)
{
string concatSuffix(string s) { return (s ~ ".ext"); }
}



dmd -m64 -c file2.d
dmd -m64 -c fileB.d

creates file2.obj and fileB.obj files

link.exe /DLL /NOENTRY file2.obj fileB.obj msvcrt.lib

fileB.obj : error LNK2019: unresolved external symbol 
_D12TypeInfo_Aya6__initZ referenced in function 
_D5fileB12concatPrefixFAyaZQe
fileB.obj : error LNK2019: unresolved external symbol 
_d_arraycatT referenced in function 
_D5fileB12concatPrefixFAyaZQe


Ok. I find _d_arraycatT in the D website at:

https://dlang.org/library/rt/lifetime/_d_arraycat_t.html

So I thought, this symbol will be in phobos64.lib.  But when I 
add it to the command, all hell breaks loose:



link.exe /DLL /NOENTRY file2.obj fileB.obj msvcrt.lib 
phobos64.lib


phobos64.lib(bits_23fa_21c.obj) : error LNK2001: unresolved 
external symbol memcpy

 o  o  o
file2.dll : fatal error LNK1120: 57 unresolved externals


So I'm stuck and don't have a clue as to how to continue.

I thought Phobos64.lib was self-contained.  Do I need to add 
other libraries?  And how do I know which ones?


You have 2 obj files, and you link them. Where do you want the 
"self contained" to be present?


The missing symbols in your case are in druntime.lib, not in 
phobos.





Re: Real simple unresolved external symbols question...

2021-02-10 Thread Kagamin via Digitalmars-d-learn

Add libraries that provide missing symbols.


Re: GC.addRange in pure function

2021-02-10 Thread Dominikus Dittes Scherkl via Digitalmars-d-learn

On Tuesday, 9 February 2021 at 21:00:39 UTC, Paul Backus wrote:

On Tuesday, 9 February 2021 at 19:53:27 UTC, Temtaime wrote:

pure is broken. Just don't [use it]


Allowing memory allocation in pure code in a language that can 
distinguish between pointer equality and value equality is, 
let's say, "unprincipled."


pure in D is a very useful concept, even if it's not literally 
the same as pure in functional languages. Recommending not to use 
it is bad advice IMHO.