Re: CTFE write message to console

2024-04-05 Thread Carl Sturtivant via Digitalmars-d-learn

On Friday, 5 April 2024 at 07:37:20 UTC, Paolo Invernizzi wrote:

pragma(msg, x) ?


No.

`__ctfeWrite(x)` is executed inside an executing function like 
any other statement in it, and can have an argument `x` computed 
during that execution.


It is defined to output the computed text `x` to stderr when the 
function it is a part of is called as CTFE by the compiler and to 
be a no-op if that function is called at run time in the compiled 
executable.


So it is a replacement for `std.stdio.write` in a CTFE function, 
handy among other things for reporting what's going on during the 
execution of that function by the compiler.


`pragma(msg, x)` works during its *compilation*, so putting it as 
a line in a CTFE-called function would not execute it when the 
function is called by the compiler. That being the case, `x` may 
not be a value computed when that function executes. Such a value 
is "not available at compile time", only at CTFE run time. The 
CTFE function is not running when it is being compiled.


It is possible that `x` in `pragma(msg, x)` be computed with a 
call to a function as its return value, i.e. computed by CTFE, 
but that call will be made when `pragma(msg, x)` is compiled, and 
is a part of compiling it. Only when the function has returned 
producing `x` does the `pragma(msg, x)` do its work.


Re: CTFE write message to console

2024-04-04 Thread Carl Sturtivant via Digitalmars-d-learn
On Thursday, 4 April 2024 at 15:47:53 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

Oh hey!

https://github.com/dlang/dmd/pull/16250

It was implemented literally 2 weeks ago!

Nightly should have it 
https://github.com/dlang/dmd/releases/tag/nightly


Wow! Happy that's in. It was a bit mysterious, but now that 
request says it was never implemented. Until now. Just what I 
want!


Re: CTFE write message to console

2024-04-04 Thread Carl Sturtivant via Digitalmars-d-learn
On Thursday, 4 April 2024 at 15:07:21 UTC, Richard (Rikki) Andrew 
Cattermole wrote:


Ah yes, I forgot about that particular thing, doesn't see much 
use as far as I'm aware.


It should be working though.


```D
enum X = computeX("A message");

string computeX(string msg) {
auto s = "CTFE msg: ";
auto x = imported!"std.format".format("%s%s\n", s, msg);
__ctfeWrite(x);
return x;
}

void main() {
import std.stdio;
writeln(X);
}
```
Produces no output on compilation, and writes out `CTFE msg: A 
message` when run.




Re: CTFE write message to console

2024-04-04 Thread Carl Sturtivant via Digitalmars-d-learn
On Thursday, 4 April 2024 at 14:06:19 UTC, Richard (Rikki) Andrew 
Cattermole wrote:


```d
static assert(0, "message");
```

Or if it is known to be CTFE'd

```d
assert(0, "message");
```

Just a warning, its a one time use only for both.

No other way to do it.


That's ... unfortunate.

Some search of the forum led me to some [decade plus old 
discussion](https://forum.dlang.org/post/j1n1m2$24p0$1...@digitalmars.com) of a possible CTFE writeln function that would be a no-op at runtime, which to my surprise led me to find [core_builtins.__ctfeWrite](https://dlang.org/phobos/core_builtins.html#.__ctfeWrite) but when I tried it out, it compiled yet output no text to the console. Given your remarks I suppose I should have expected this.


Re: std.traits.ParameterIdentifierTuple problem

2024-04-02 Thread Carl Sturtivant via Digitalmars-d-learn

On Monday, 1 April 2024 at 18:28:16 UTC, Nick Treleaven wrote:

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?


1. For compile time work that uses the name but not the function 
it nominally refers to. That's what I wanted it for: 
`ParameterIdentifierTuple` might actually work on that.


2. In fact the definition might refer to a function defined in 
another module, for example brought in by ImportC. It's an 
alternative way of writing the signature of an external function. 
Why rule it out when it is reasonable?


The first could also work with an explicitly uninstantiated 
function, as in `enum FUNCTYPE f = void;` hence my second attempt 
above.


As long as there are compile-time actions that work on functions 
but not their types, this would be a way to work around that.





Re: std.traits.ParameterIdentifierTuple problem

2024-03-31 Thread Carl Sturtivant via Digitalmars-d-learn

On Sunday, 31 March 2024 at 11:35:39 UTC, Nick Treleaven wrote:
If a function type does include identifiers, then would two 
function types with the same argument types but different 
identifiers compare equal using `is`?


Yes. That is the idea. Define `is` to work this way.


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?





Re: std.traits.ParameterIdentifierTuple problem

2024-03-30 Thread Carl Sturtivant via Digitalmars-d-learn

On Saturday, 30 March 2024 at 22:37:53 UTC, Carl Sturtivant wrote:

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, but the 
compiler said `bug1.d(5): Error: variable ``bug1.func`` cannot 
be declared to be a function`. Seems unreasonable given the 
implied semantics.


The word *variable* in that error message caught my eye and it 
struck me that in some sense a function is a constant, not a 
variable, we have function pointers for the last. So I tried

```D
enum typeof(foo) func = void;
```
to see if I could escape this difficulty. Sadly got exactly the 
same error message, even though no variable was involved.


Re: std.traits.ParameterIdentifierTuple problem

2024-03-30 Thread Carl Sturtivant via Digitalmars-d-learn

On Saturday, 30 March 2024 at 21:07:35 UTC, Nick Treleaven wrote:
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.


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.


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, but the 
compiler said `bug1.d(5): Error: variable ``bug1.func`` cannot be 
declared to be a function`. Seems unreasonable given the implied 
semantics.




Re: std.traits.ParameterIdentifierTuple problem

2024-03-30 Thread Carl Sturtivant via Digitalmars-d-learn

On Saturday, 30 March 2024 at 21:51:34 UTC, Nick Treleaven wrote:
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.


I appreciate you actually having a shot at this! No apology 
necessary!




Re: std.traits.ParameterIdentifierTuple problem

2024-03-30 Thread Carl Sturtivant via Digitalmars-d-learn

On Saturday, 30 March 2024 at 21:07:35 UTC, Nick Treleaven wrote:
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.


OK, so how can I get them? Am I forced to take that string and 
parse it with CTFE?


std.traits.ParameterIdentifierTuple problem

2024-03-30 Thread Carl Sturtivant via Digitalmars-d-learn
Using the 
[ParameterIdentifierTuple](https://dlang.org/phobos/std_traits.html#ParameterIdentifierTuple) example just there, with one more step stops working. Details:

```D
import std.traits;
int foo(int num, string name, int);
static assert([ParameterIdentifierTuple!foo] == ["num", "name", 
""]);


alias signature = typeof(foo);
pragma(msg, signature.stringof);
enum names = [ParameterIdentifierTuple!signature];
pragma(msg, names.stringof);
static assert(names==["num","name",""], "wrong!");
```
Output on compilation:
```
$ dmd --version
DMD64 D Compiler v2.107.0
Copyright (C) 1999-2024 by The D Language Foundation, All Rights 
Reserved written by Walter Bright


$ 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?




Re: Hidden members of Class objects

2024-03-26 Thread Carl Sturtivant via Digitalmars-d-learn
On Thursday, 7 March 2024 at 00:38:30 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
Yes its opt-in. 
https://dlang.org/spec/statement.html#synchronized-statement


As you mentioned in another thread there's handy ABI 
documentation for classes and interfaces just here 
[https://dlang.org/spec/abi.html#classes](https://dlang.org/spec/abi.html#classes) that spells out the story.


Re: DFLAGS and DMD Windows

2024-03-21 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 21 March 2024 at 18:17:00 UTC, Carl Sturtivant wrote:
On Wednesday, 20 March 2024 at 22:53:13 UTC, Carl Sturtivant 
wrote:
Is it me, or does the [DFLAGS environment 
variable](https://dlang.org/dmd-windows.html#environment) have 
no effect on DMD.

```
dmd --version
DMD64 D Compiler v2.107.0
```


Anyone?


Well, the docs are bogus.
https://issues.dlang.org/show_bug.cgi?id=1660
Would have been nice if they'd mentioned this.



Re: ImportC GUID compilation problem with some Windows headers

2024-03-21 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 21 March 2024 at 22:33:17 UTC, Dave P. wrote:
I filed a bug for this: 
https://issues.dlang.org/show_bug.cgi?id=24447


I haven’t tried on  a windows box and this is just from me 
grepping through header files, but maybe try to `#define 
EXTERN_C` as nothing in the meantime?


I'll give it a shot. Thanks for the bug report.



Re: DFLAGS and DMD Windows

2024-03-21 Thread Carl Sturtivant via Digitalmars-d-learn
On Wednesday, 20 March 2024 at 22:53:13 UTC, Carl Sturtivant 
wrote:
Is it me, or does the [DFLAGS environment 
variable](https://dlang.org/dmd-windows.html#environment) have 
no effect on DMD.

```
dmd --version
DMD64 D Compiler v2.107.0
```


Anyone?


Re: ImportC GUID compilation problem with some Windows headers

2024-03-21 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 21 March 2024 at 00:06:56 UTC, Carl Sturtivant wrote:

```C
EXTERN_GUID(IID_IBlahBlahBlah, 0xabcdef12, 0x11d2, 0xab3a, 
0xc0, 0x4f, [...] );

```


Has anyone successfully compiled an EXTERN_GUID declaration like 
this in a Windows header with ImportC using some C macro trickery 
for example?





ImportC GUID compilation problem with some Windows headers

2024-03-20 Thread Carl Sturtivant via Digitalmars-d-learn
I'm running into this COM related issue with some Windows 
headers, in the case when each GUID is declared in such a file as 
follows.

```C
EXTERN_GUID(IID_IBlahBlahBlah, 0xabcdef12, 0x11d2, 0xab3a, 0xc0, 
0x4f, [...] );

```
and ImportC which is compiling `blah.c` containing only a few 
macro definitions and a single include of a header file say 
 encounters these and responds with

```
[...] waffle.h(123): Error: variable `waffle.IID_IBlahBlahBlah` 
extern symbols cannot have initializers

```
Presumably MSVC simply compiles such files, but DMD's ImportC is 
too strict to do so. I've worked around this in some very dirty 
and inconvenient ways, but am hoping for a real solution of some 
kind. I want to use some of these IIDs and CLSIDs so I need to 
make these declarations work in some fashion. Inclusions are 
nested so these may be far from the header file I am including in 
`blah.c`. Any help appreciated.


Re: Need help with Windows linkage ( DMD using ImportC)

2024-03-20 Thread Carl Sturtivant via Digitalmars-d-learn
I found a way to make a solution for 64 bit Windows mechanically 
with many MSVC intrinsics, using only mingw64.

Here's an [MSYS2](https://www.msys2.org/) bash script.
```bash
gcc -E -P intrin.c -o vcintrinsics.c

sed -i 's/extern __inline__ 
__attribute__((__always_inline__,__gnu_inline__))//g' 
vcintrinsics.c


gcc -fPIC -shared -o vcintrinsics.dll vcintrinsics.c 
-Wl,--export-all-symbols -Wl,--output-def=vcintrinsics.def


#lib -nologo -machine:x64 -def:vcintrinsics.def 
-out:vcintrinsics.lib


dlltool -D vcintrinsics.dll -d vcintrinsics.def -l 
vcintrinsics.lib -m i386:x86-64


cp vcintrinsics.dll /c/D/dmd2/windows/bin64/
cp vcintrinsics.lib /c/D/dmd2/windows/lib64/
```
The commented out line is using the MS librarian to do the same 
job as the mingw64 libtool. This script builds a dll containing 
100+ intrinsics defined in mingw64 and makes an import library 
for DMD to use it from a developer command prompt.


`intrin.c` contains only `#include ` and is 
preprocessed in the first line into `vcintrinsics.c` which if 
examined contains working definitions of many intrinsics but with 
`extern __inline__ 
__attribute__((__always_inline__,__gnu_inline__))` prefixing 
them, so they will not compile to actual library functions. The 
sed command strips those prefixes out, and the compilation makes 
a DLL containing the the intrinsics and a DEF file listing their 
names for linkage, ready for dlltool to assemble an import 
library suitable for DMD to link to so as to be able to 
dynamically link the DLL.


And that's it; so far the result has just worked and I've had no 
linkage issues due to missing MSVC intrinsics since. I just put 
vcintrinsics.lib on the end of the dmd command line whenever I'm 
using real Windows headers in ImportC and the linker has always 
been satisfied so far. When I'm done, I can remove vcintrinsics 
from the dmd command line, and find out which intrinsics are 
actually needed for linking, and using the technique earlier in 
the thread above, satisfy those directly, so the result doesn't 
need vcintrinsics.dll.


Hopefully DMD will soon know about these MSVC intrinsics but 
until then this is an effective way to more-or-less permanently 
work around the inevitable linkage problems.


DFLAGS and DMD Windows

2024-03-20 Thread Carl Sturtivant via Digitalmars-d-learn
Is it me, or does the [DFLAGS environment 
variable](https://dlang.org/dmd-windows.html#environment) have no 
effect on DMD.

```
dmd --version
DMD64 D Compiler v2.107.0
```



Re: Need help with Windows linkage ( DMD using ImportC)

2024-03-10 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 7 March 2024 at 18:14:32 UTC, Gregor Mückl wrote:
2. C code referring to MSVC-specific compiler intrinsics. At 
least InterlockedExchangeAdd, InterlockedExchangeAdd64 and 
_stosb are such intrinsics. This is harder to resolve. There 
are two ways forward here: either implement a shim function 
that replicates the intrinsic's functionality if possible or 
add support for these intrinsics to DMD.


Thanks for the explanation, on the strength of which I found a 
way to deal with this correctly.


I made `intrinsics1.c` that has `#include ` and 
contains an actual function for each missing intrinsic; e.g. for 
the missing __shiftright128 it has

```C
unsigned __int64 D__shiftright128(
   unsigned __int64 LowPart,
   unsigned __int64 HighPart,
   unsigned char Shift
)
{ return __shiftright128(LowPart, HighPart, Shift); }

```
where I got the prototypes from this [list of 
intrinsics](https://learn.microsoft.com/en-us/cpp/intrinsics/alphabetical-listing-of-intrinsic-functions?view=msvc-170).


Compiling this with MSVC `cl -c intrinsics1.c` produces a COFF 
object `intrinsics1.obj` containing an actual function to link to 
for each intrinsic. So this stage writes the code so we don't 
have to.


As a matter of necessity, the names of the functions in 
`intrinsics1.c` representing the MSVC intrinsics are not the same 
as their actual names. By my convention above they are prefixed 
with "D". Now we could simply write an extern(C) D function in a 
module say `vcintrinsics.d`, that has exactly the intrinsic's 
name, and calls the "D" prefixed function linked from 
`intrinsics1.obj`, e.g. for the above example `vcintrinsics.d` 
could contain

```D
extern(C):

extern ulong D__shiftright128(ulong LowPart, ulong HighPart, 
ubyte Shift);


ulong __shiftright128(ulong LowPart, ulong HighPart, ubyte Shift){
return D__shiftright128(LowPart, HighPart, Shift);
}
```
As DMD doesn't know of these intrinsics, it won't complain about 
defining a function with exactly the same name as an intrinsic so 
as to implement that intrinsic as an actual function, solving the 
problem. `dmd -lib vcintrinsics.d intrinsics1.obj` then produces 
a library that resolves the linkage issue.


An alternative not involving having two function calls to 
implement an intrinsic is to compile `intrinsics1.c` with MSVC 
into a DLL, and using a DEF file that renames the exports just 
like part of the solution 
[here](https://forum.dlang.org/post/ruupyklfkrvnjtker...@forum.dlang.org) make those functions available under their original names when linking to its import library.


A lot of both of the above is boilerplate and can be automated. 
It would be even nicer if the MSVC tools could be persuaded to 
proceed in a similar way with DEF file renaming when building a 
static library, but I have not succeeded in making this happen. 
Anyone?


Re: DMD windows and Clang's llvm-link.exe

2024-03-09 Thread Carl Sturtivant via Digitalmars-d-learn
On Sunday, 10 March 2024 at 04:22:20 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

On 10/03/2024 4:46 PM, Carl Sturtivant wrote:
suggesting that there's a reason version 9 instead of 17 of 
lld is being used in the latest DMD installation, that may be 
relevant what I'd like to try. Any idea what that might be?


Yes, nobody has updated it.

https://github.com/dlang/installer/blob/50f5825e9d9bf44afb9108f0c1a01a8038d2f156/.github/workflows/build_windows.yml#L22

The ldc one should match whatever LLVM is which is newer.


No technical reason then, I assume you mean.


Re: DMD windows and Clang's llvm-link.exe

2024-03-09 Thread Carl Sturtivant via Digitalmars-d-learn
On Saturday, 9 March 2024 at 22:07:05 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

lld is used and distributed with dmd and ldc.

That is known to work.

If you have MSVC, it'll prefer that however.


Interesting, perhaps I should have known that, though I have not 
used DMD on Windows for many years until now.


I have this from a 64-bit "Developer Command Prompt":
```

lld-link --version
LLD 9.0.0 (https://github.com/dlang/installer 
d4266cf3dccfd7a7d361d28143f86e98b2da8db8)

dmd --version

DMD64 D Compiler v2.107.0
Copyright (C) 1999-2024 by The D Language Foundation, All Rights 
Reserved written by Walter Bright

```
Whereas from an MSYS2 Clang64 terminal I have this:
```
$ lld-link --version
LLD 17.0.6$ clang --version
clang version 17.0.6
```
suggesting that there's a reason version 9 instead of 17 of lld 
is being used in the latest DMD installation, that may be 
relevant what I'd like to try. Any idea what that might be?




DMD windows and Clang's llvm-link.exe

2024-03-09 Thread Carl Sturtivant via Digitalmars-d-learn
I'd like to see if I can get dmd to work correctly with Clang 
rather than MS tools. Can anyone share any experience they've had 
with this or any understanding of the situation?




Re: Need help with Windows linkage ( DMD using ImportC)

2024-03-09 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 7 March 2024 at 18:14:32 UTC, Gregor Mückl wrote:
1. Missing import libraries for Win32 API functions. Anything 
starting with `__imp_` is a symbol that should be provided by a 
DLL import library. MapViewOfFileNuma2 for example is provided  
by onecore.lib in the Windows SDK, according to Microsoft 
documentation.


Onecore: not sure what I did to add that dependency. Two symbols 
there. Thanks for the __imp_ clue.


2. C code referring to MSVC-specific compiler intrinsics. At 
least InterlockedExchangeAdd, InterlockedExchangeAdd64 and 
_stosb are such intrinsics. This is harder to resolve. There 
are two ways forward here: either implement a shim function 
that replicates the intrinsic's functionality if possible or 
add support for these intrinsics to DMD.


Yes, not sure what the potential consequences are for my dirty 
replacement. Presumably DMD itself won't generate code using 
these, but ...




Re: Hidden members of Class objects

2024-03-06 Thread Carl Sturtivant via Digitalmars-d-learn

On Wednesday, 6 March 2024 at 23:45:00 UTC, H. S. Teoh wrote:
In D, there's a pointer to the vtable and another pointer to a 
Monitor object (used for synchronized methods).  There was talk 
about getting rid of the Monitor field years ago, but nothing 
has happened yet.


Very interesting: is the monitor field ever touched by compiled D 
code at any point nowadays? Or is it just vestigial?




Hidden members of Class objects

2024-03-06 Thread Carl Sturtivant via Digitalmars-d-learn
I notice that a class with no data members has a size of two 
words (at 64 bits). Presumably there's a pointer to a table of 
virtual functions, and one more. Is the Vtable first?


A COM class that inherits from IUnknown and has no data members 
has a size of three words, presumably as before plus something 
that ordinarily is in the Vtable but can't be for a COM object as 
it has its own layout of that.


What is actually in these objects using that space?


Re: Need help with Windows linkage ( DMD using ImportC)

2024-03-04 Thread Carl Sturtivant via Digitalmars-d-learn

On Monday, 4 March 2024 at 21:21:20 UTC, Carl Sturtivant wrote:

```
blah.obj: error LNK2019: unresolved external symbol _mul128 
referenced in function MultiplyExtract128
blah.obj: error LNK2019: unresolved external symbol 
__shiftright128 referenced in function MultiplyExtract128
blah.obj: error LNK2019: unresolved external symbol _umul128 
referenced in function UnsignedMultiplyExtract128
blah.obj: error LNK2019: unresolved external symbol __stosb 
referenced in function RtlSecureZeroMemory
blah.obj: error LNK2019: unresolved external symbol 
__readgsqword referenced in function NtCurrentTeb
blah.obj: error LNK2019: unresolved external symbol 
__imp_MapViewOfFileNuma2 referenced in function MapViewOfFile2
blah.obj: error LNK2019: unresolved external symbol 
__imp_CharUpperW referenced in function ua_CharUpperW

```


I forced linkage of these unused symbols as follows, but it would 
be nice to have a clean way to proceed.

```D
extern(C) {
int _InterlockedExchangeAdd(int* Addend, int Value) { return 
0; };
long _InterlockedExchangeAdd64(long* Addend, long Value) { 
return 0; }

void _mul128() {};
void __shiftright128() {};
void _umul128() {};
void __stosb() {};
void __readgsqword() {};
void __imp_MapViewOfFileNuma2() {};
void __imp_CharUpperW() {};
}
```
I got the D signatures of the first two so as to generate the 
correct linkage by using ImportC to translate the inclusion of 
`Windows.h` into a .di file, and searching.


Re: Using ImportC to augment a big C project with D

2024-02-21 Thread Carl Sturtivant via Digitalmars-d-learn
On Tuesday, 20 February 2024 at 18:33:42 UTC, Carl Sturtivant 
wrote:

1.
When the resulting executable runs it will have D call C which 
in turn calls D. In that last D (the D files replacing some C 
files), if I throw an exception and don't catch it in the D 
files that replace some C files, will it propagate correctly to 
the D main function where I can catch it?


My understanding is that [this 
reply](https://forum.dlang.org/post/ur5g46$fmb$1...@digitalmars.com) 
indicates that this works. Exceptions thrown by D can be caught 
by D in general in the presence of ImportC.



2.
The C source calls exit() from C's stdlib, and D needs to 
terminate properly. Throwing an exception and catching it in 
D's main function seems to be a way to achieve this. What is 
the best way to deal with exit() ?


So I can simulate C's exit() by throwing an exception and 
catching it in main() as [suggested 
here](https://forum.dlang.org/post/mailman.5856.1600355565.31109.digitalmars-d-le...@puremagic.com).



3.
I want to use D's remarkable Fiber class to reimplement a 
deterministic stack changing context switch that in the 
original project is achieved with assembly code on a 
per-platform basis. This will mean that D's main function will 
call C which will call D which will effect a context switch. Is 
there any reason to believe this will work as naively hoped?


I'll have to proceed experimentally, but I'd like to know in 
advance if this is doomed. Anyone?


Re: Using ImportC to augment a big C project with D

2024-02-21 Thread Carl Sturtivant via Digitalmars-d-learn
On Wednesday, 21 February 2024 at 12:45:50 UTC, Bastiaan Veelo 
wrote:
What do you mean by "need"? You can call 
https://dlang.org/phobos/core_stdc_stdlib.html#.exit from D:


Of course, but does it respect D shutdown?


Output:
```
onlineapp._sharedStaticDtor_L11_C1
```

So it does run module destructors, but not `scope(exit)` 
statements (which probably makes sense).


So it doesn't respect D shutdown, i.e. what happens when 
returning from main with an error code.


I would expect `exit()` called from the C source to have 
similar results.


Why is that?

I just found this.
[Proper way to exit with specific exit 
code?](https://forum.dlang.org/thread/bavfkowjjcijeshrt...@forum.dlang.org)








Using ImportC to augment a big C project with D

2024-02-20 Thread Carl Sturtivant via Digitalmars-d-learn
I just saw the announcement that macros with parameters are now 
translated into D by ImportC. Incredible! Congratulations to all 
involved.


As an occasional D user, I have long wanted a fast route to using 
D with an existing large C project (100K lines approximately).


I want to replace the C main program with a D main function that 
calls the old C main function (suitably renamed) to change the 
command line arguments that can be supplied, and with the helpful 
side effect that druntime is properly initialized. I want to 
replace some C files with D ones. (I am cognizant of GC issues 
here, this is not what I am asking about.)


Now I can use ImportC with all of the header files to make the D 
replacement files easy to write correctly. Perhaps I can use 
ImportC for all of the C source.


1.
When the resulting executable runs it will have D call C which in 
turn calls D. In that last D (the D files replacing some C 
files), if I throw an exception and don't catch it in the D files 
that replace some C files, will it propagate correctly to the D 
main function where I can catch it?


2.
The C source calls exit() from C's stdlib, and D needs to 
terminate properly. Throwing an exception and catching it in D's 
main function seems to be a way to achieve this. What is the best 
way to deal with exit() ?


3.
I want to use D's remarkable Fiber class to reimplement a 
deterministic stack changing context switch that in the original 
project is achieved with assembly code on a per-platform basis. 
This will mean that D's main function will call C which will call 
D which will effect a context switch. Is there any reason to 
believe this will work as naively hoped?





Re: std.uni.CodepointSet from range of pairs of integers

2024-02-19 Thread Carl Sturtivant via Digitalmars-d-learn
On Monday, 19 February 2024 at 04:47:07 UTC, Richard (Rikki) 
Andrew Cattermole wrote:

On 19/02/2024 5:33 PM, Carl Sturtivant wrote:
On Monday, 19 February 2024 at 01:42:03 UTC, Richard (Rikki) 
Andrew Cattermole wrote:


Indeed, nothing in that function body would suggest it needs to 
be a forward range.


Ah yup, the body was changed but never updated its template 
conditional.


https://github.com/dlang/phobos/commit/c9f1c42ed3a8bb92e48bf400ce2f31f434a99905


Thank you for looking into this.


Re: std.uni.CodepointSet from range of pairs of integers

2024-02-19 Thread Carl Sturtivant via Digitalmars-d-learn
On Monday, 19 February 2024 at 01:42:03 UTC, Richard (Rikki) 
Andrew Cattermole wrote:

I can understand ``pure``.

https://github.com/dlang/phobos/blob/master/std/uni/package.d#L2075

It is literally on the constructor.


I should have noticed this!



Re: std.uni.CodepointSet from range of pairs of integers

2024-02-18 Thread Carl Sturtivant via Digitalmars-d-learn
On Monday, 19 February 2024 at 01:42:03 UTC, Richard (Rikki) 
Andrew Cattermole wrote:

I can understand ``pure``.

https://github.com/dlang/phobos/blob/master/std/uni/package.d#L2075

It is literally on the constructor.

Now @safe I don't know. My best guess would be for some reason 
the constructor is getting inferred as it (templates get 
inferred).


What about needing a forward range, not just an input range? It 
would seem it just needs to iterate through a sequence of pairs 
of integers.


std.uni.CodepointSet from range of pairs of integers

2024-02-18 Thread Carl Sturtivant via Digitalmars-d-learn
I wanted to construct a CodepointSet from a string, so I used the 
constructor here.

https://dlang.org/phobos/std_uni.html#.InversionList.this.2

I wrote a range of pairs (CodepointIntervals) of integers 
consisting of each codepoint in the string paired with that plus 
one. This did solve the problem, but only after I overcame some 
peculiarities of the situation.


Specifically, this required a forward range, not just an input 
range, so I wrote a save method.


Once I fixed that problem, it needed empty() and popFront() to be 
pure. So I added the word pure to each in my range.


Once I fixed that problem, it required those to be @safe, so I 
added that to my struct declaration of my range.


Then everything worked.

Could I have anticipated any of this, and what is the reason for 
each of these?





Re: std.uni CodepointSet toString

2024-02-08 Thread Carl Sturtivant via Digitalmars-d-learn

On Wednesday, 7 February 2024 at 17:11:30 UTC, H. S. Teoh wrote:
Do we know why the compiler isn't getting it right?  Shouldn't 
we be fixing it instead of just turning off elision completely?


This matter seems to have been an issue for some time.
https://forum.dlang.org/post/l5e5hm$1177$1...@digitalmars.com



Re: std.uni CodepointSet toString

2024-02-07 Thread Carl Sturtivant via Digitalmars-d-learn
On Wednesday, 7 February 2024 at 11:49:20 UTC, Richard (Rikki) 
Andrew Cattermole wrote:

```
undefined reference to 
`_D4core9exception__T15__switch_errorTZQsFNaNbNiNeAyamZv'

collect2: error: ld returned 1 exit status
Error: linker exited with status 1
```


Use ``-allinst``, that is a template emission bug.


!
Thanks, at least I can continue now, though presumably the cure 
has its own problems.


```
$ dmd --help | grep allinst
  -allinst  generate code for all template instantiations
```
Unclear exactly how -allinst does this, given type parameters, 
and it will affect all of the many templates I use in source with 
CodepointSet.


Can you shed any light?



std.uni CodepointSet toString

2024-02-06 Thread Carl Sturtivant via Digitalmars-d-learn

Need help working around a linkage problem.
```d
import std.uni, std.conv, std.stdio, std.format;

void main() {
//auto c1 = unicode.InBasic_latin;
auto c1 = CodepointSet('a','z'+1);
writeln(c1.to!string);
writeln(format("%d", c1));
writeln(format("%#x", c1));
writeln(format("%#X", c1));
writefln("%s", c1);
}
```
doesn't link, but does link with the commented out CodepointSet 
instead. Combines code from these examples at the following URLs.

https://dlang.org/phobos/std_uni.html#InversionList
https://dlang.org/phobos/std_uni.html#.InversionList.toString
```
$ dmd --version
DMD64 D Compiler v2.107.0
Copyright (C) 1999-2024 by The D Language Foundation, All Rights 
Reserved written by Walter Bright

$ dmd cset2.d
/usr/bin/ld: cset2.o: in function 
`_D4core8internal7switch___T14__switch_errorZQrFNaNbNiNfAyamZv':

cset2.d:(.text._D4core8internal7switch___T14__switch_errorZQrFNaNbNiNfAyamZv[_D4core8internal7switch___T14__switch_errorZQrFNaNbNiNfAyamZv]+0x19):
 undefined reference to 
`_D4core9exception__T15__switch_errorTZQsFNaNbNiNeAyamZv'
collect2: error: ld returned 1 exit status
Error: linker exited with status 1
```




Re: Scripting with Variant from std.variant: parameter passing

2024-02-03 Thread Carl Sturtivant via Digitalmars-d-learn

On Friday, 2 February 2024 at 20:58:12 UTC, Paul Backus wrote:

Another variation on the same theme:
```d
/// map over a variadic argument list
template mapArgs(alias fun)
{
auto mapArgs(Args...)(auto ref Args args)
{
import std.typecons: tuple;
import core.lifetime: forward;
import std.meta: Map = staticMap;

auto ref mapArg(alias arg)()
{
return fun(forward!arg);
}

return tuple(Map!(mapArg, args));
}
}

import std.variant: Variant;
import std.meta: allSatisfy;

enum isVariant(T) = is(T == Variant);

auto foo(Args...)(Args args)
if (!allSatisfy!(isVariant, Args))
{
return .foo(mapArgs!Variant(args).expand);
}
```


Thanks, will study the library machinery you used here.


Re: Scripting with Variant from std.variant: parameter passing

2024-02-02 Thread Carl Sturtivant via Digitalmars-d-learn
On Friday, 2 February 2024 at 19:22:22 UTC, Steven Schveighoffer 
wrote:

```d
void foo(Variant x, Variant y) { ... }

import std.meta : allSatisfy;

enum isVariant(T) = is(T == Variant);

// this is going to suck at CTFE but...
string argsAsVariants(size_t count)
{
   import std.format;
   import std.range;
   import std.alglorithm;
   import std.array;
   return iota(count).map!(i => format("Variant(args[%s])", 
i).join(",");

}

// shim
auto foo(Args...)(Args args) if (!allSatisfy!(isVariant, Args))
{
mixin("return foo(", argsAsVariants(args.length), ");");
}
```


Thanks for this idea. I'll work on it.


-Steve





Scripting with Variant from std.variant: parameter passing

2024-02-02 Thread Carl Sturtivant via Digitalmars-d-learn
It seems I cannot pass e.g. an int argument to a Variant function 
parameter. What's the simplest way to work around this 
restriction?


Re: import locality with function parameters

2024-02-01 Thread Carl Sturtivant via Digitalmars-d-learn
On Friday, 2 February 2024 at 01:23:11 UTC, Steven Schveighoffer 
wrote:

Are you thinking of this?

https://dlang.org/phobos/object.html#.imported

-Steve


Yes! Glad it's now part of D.
Thank you.




import locality with function parameters

2024-02-01 Thread Carl Sturtivant via Digitalmars-d-learn

Hello,

I seem to recall that there is surprising template to import a 
module and get a type from it inside the declaration of the type 
of a parameter to a function, so that the module need not be 
imported outside of the function definition. I think there was a 
blog article some years ago about this where there was some 
indication that this or something with equivalent effect would be 
incorporated into D in some way.


How do I define a function with a parameter that is a type in an 
outside module while keeping module import local to that 
definition?




Re: compute from a string the text of a string literal

2024-01-17 Thread Carl Sturtivant via Digitalmars-d-learn

On Wednesday, 17 January 2024 at 18:53:48 UTC, Paul Backus wrote:
There's a function that does this in Phobos, but it's 
`private`. Currently, the only way to access it is by calling 
`to!string` or `format` on a range that contains the string you 
want to convert as an element:


```d
void main()
{
import std.range, std.conv, std.stdio;

string s = `"foo"\bar`;
string escaped = only(s).to!string[1 .. $-1]; // slice off 
[ and ]

writeln(escaped); // "\"foo\"\\bar"
}
```


Great! I'll use that!



compute from a string the text of a string literal

2024-01-17 Thread Carl Sturtivant via Digitalmars-d-learn

Hello,
I'd like a function like this,
```
string image(string s)
```
that maps any string s into the doubly quoted backslash escaped 
text that would be a string literal for s were it pasted into a 
program. Perhaps with a second parameter with detailed options.


Is there something out there I could use?



Re: Anyway to achieve the following

2021-08-15 Thread Carl Sturtivant via Digitalmars-d-learn

On Sunday, 15 August 2021 at 07:10:17 UTC, JG wrote:

Hi,

This is exactly the behaviour I was trying to obtain.

It however comes with a fair amount of overhead, as can be seen 
in the following llvm ir:


[...]


What you are asking for are reference variables. C++ has them: 
the example here illustrates the behavior you want.

https://www.geeksforgeeks.org/references-in-c/

D does not have them, as mentioned above:
https://forum.dlang.org/post/mailman.2714.1628875187.3446.digitalmars-d-le...@puremagic.com

So to get the behavior you want, they have to be simulated, which 
is what this does:

https://forum.dlang.org/post/lcrrnszslpyazoziy...@forum.dlang.org

Next version: no `toString` and storage passed in by reference 
rather than by pointer.


```
struct S {
  int x = 1234;
}

void main() {
  import std.stdio;
   S s;
   auto p = &s.x;
   //construction of a using &(s.x)
   auto a = Ref!(int)(*p);
   //auto a = Ref!(int)(s.x);
   writeln(a); //displays 1234
   s.x += 1;
   writeln(a); //displays 1235
   a += 1;
   writeln(s.x); //displays 1236
}

struct Ref(T)
{
  T* ptr;
  this(ref T x) { ptr = &x; }
  @property ref T var() { return *ptr; }
  alias var this;
}
```

I see no way to avoid overhead, as I see no simpler simulation.



Re: Anyway to achieve the following

2021-08-14 Thread Carl Sturtivant via Digitalmars-d-learn

```
struct S {
  int x = 1234;
}

void main() {
  import std.stdio;
   S s;
   //construction of a using &(s.x)
   auto a = Ref!(int)(&s.x);
   writeln(a); //displays 1234
   s.x += 1;
   writeln(a); //displays 1235
   a += 1;
   writeln(s.x); //displays 1236
}

struct Ref(T) {
  T* ptr;
  this(T* p) { ptr = p; }
  string toString() { import std.conv; return to!string(*ptr); }
  ref T var() { return *ptr; }
  alias var this;
}
```


Re: alias restriction??!

2020-07-20 Thread Carl Sturtivant via Digitalmars-d-learn

On Monday, 20 July 2020 at 17:24:56 UTC, Carl Sturtivant wrote:
Well perhaps you do parse a "constant-offset expression" i.e. 
syntactically dotted with constant indexes, like 
name1.name2[constant].name3 and then later there's a semantic 
check that the "constant-offset expression" involves no 
indirections when an offset into the top level object is 
computed. Then it's treated like any other attribute of a 
struct with a known offset.


Perhaps this could also work for a class at the top with 
recursively embedded structs and value arrays.


Re: alias restriction??!

2020-07-20 Thread Carl Sturtivant via Digitalmars-d-learn
On Sunday, 19 July 2020 at 20:46:19 UTC, Steven Schveighoffer 
wrote:

On 7/19/20 4:21 PM, Carl Sturtivant wrote:


Perhaps what's needed is something more that is less than 
allowing aliases for expressions in the wide sense you suggest 
here.


I agree. Something not yet mentioned is that aliases provide 
direct access to the symbols for the purposes of looking at 
attributes -- something that a wrapper function doesn't provide.


The question is: how do you restrict it to explicit data items 
within a specific aggregate without parsing arbitrary 
expressions?


Well perhaps you do parse a "constant-offset expression" i.e. 
syntactically dotted with constant indexes, like 
name1.name2[constant].name3 and then later there's a semantic 
check that the "constant-offset expression" involves no 
indirections when an offset into the top level object is 
computed. Then it's treated like any other attribute of a struct 
with a known offset.


Re: alias restriction??!

2020-07-19 Thread Carl Sturtivant via Digitalmars-d-learn

On Sunday, 19 July 2020 at 17:06:14 UTC, Paul Backus wrote:
Also, letting aliases refer to expressions essentially allows 
AST macros in through the back door. Consider the following 
example:


[...]


Perhaps what's needed is something more that is less than 
allowing aliases for expressions in the wide sense you suggest 
here.


Re: alias restriction??!

2020-07-19 Thread Carl Sturtivant via Digitalmars-d-learn

On Sunday, 19 July 2020 at 12:08:07 UTC, Paul Backus wrote:
On Saturday, 18 July 2020 at 18:46:16 UTC, Carl Sturtivant 
wrote:

Here's a toy version of a problem in the wild.

struct S {
long first;
union T {
long one;
double two;
}
T second;
alias First = first;
alias Second = second.one;
}

void main() {
S x;
x.First = 4;
x.Second = 5; // compilation error: "Error: need this for 
one of type long"

}


Easiest workaround:

ref inout(long) Second() inout { return second.one; }


Was trying to avoid this for performance reasons. In fact what 
are the performance implications of this sort of thing with 
current implementations? --- relative to using a simple offset.




alias restriction??!

2020-07-18 Thread Carl Sturtivant via Digitalmars-d-learn

Here's a toy version of a problem in the wild.

struct S {
long first;
union T {
long one;
double two;
}
T second;
alias First = first;
alias Second = second.one;
}

void main() {
S x;
x.First = 4;
x.Second = 5; // compilation error: "Error: need this for one 
of type long"

}

Second is a fixed offset into an S and it would be nice to have a 
name for it. Why doesn't alias know it's OK?


I can work around this with some duplication as follows.

struct S {
long first;
union {
long one;
double two;
union T {
long one;
double two;
}
T second;
}
alias First = first;
alias Second = one;
}

void main() {
S x;
x.First = 4;
x.Second = 5;
x.second.one = 6;
import std.stdio;
writeln(x);
writeln(x.one);
writeln(x.Second);
}

Is there any way to avoid the duplication of the entries in the 
anonymous union, aside from using a mixin template?


Is there some other way (not involving writing a function) to 
work around this?




Re: How do I display unicode characters in D on standard (english) Windows 10 console window?

2019-07-31 Thread Carl Sturtivant via Digitalmars-d-learn

On Monday, 29 July 2019 at 22:17:55 UTC, WhatMeWorry wrote:
This is a very stupid question but from Ali's book, I took this 
segment:



writeln("Résumé preparation: 10.25€");
writeln("\x52\ésum\u00e9 preparation: 10.25\€");


and after running it all I get is the following:


Résumé preparation: 10.25€
Résumé preparation: 10.25€


I was expecting the symbol "£" or something like that.  What am 
I missing?


In my Windows 10 build 1803 I was able to find a box to check to 
globally use the UTF-8 code page. Checking it requires a restart 
as it says the locale has changed.


Settings>Time&Language>Region&Language>Administrative_Language_Settings
brings up a Region dialog, and clicking on "Change system 
locale..." brought up a dialog where this box can be checked.


After doing this the console acted sensibly right away with the 
code you wrote.


Re: opDispatch doesn't play nice with inheritance

2018-11-17 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 15 November 2018 at 19:01:45 UTC, Ali Çehreli wrote:

On 11/15/2018 09:14 AM, Carl Sturtivant wrote:

> opDispatch is special in that it allows for functions to be
added to a
> class or struct when undefined overtly but used elsewhere but
it seems
> those functions sadly are final.
>
> Can anything useful be done to remedy the situation?

For the compiler to be able to make all opDispatch 
instantiations virtual, it would have to first see all calls 
that generate opDispatch instantiations. (Impossible in the 
presence of separate compilation.)


Only then the compiler would know how large the vtbl of the 
base class should be and what member functions of the derived 
class are overrides of those virtual functions.


I suppose it's such administrative difficulties that led to D 
defining anything that might conceivably be overridden to be 
virtual, whether or not actually overridden.




Re: opDispatch doesn't play nice with inheritance

2018-11-15 Thread Carl Sturtivant via Digitalmars-d-learn
On Thursday, 15 November 2018 at 18:04:42 UTC, Adam D. Ruppe 
wrote:

Right, all templates are final, including opDispatch.

What I've done in the past is to forward them to a virtual 
function with runtime arguments instead of compile time 
arguments.


Kinda like:

void opDispatch(string name)() {
 callMethod(name);
}

/* virtual */ void callMethod(string name) {
 // do a reflection loop or associate array or switch or 
whatever to dispatch it here, reimplemented (or at least 
re-mixed-in) in the child classes to account for their new 
methods

}



What exactly do you need to do with it? Maybe you can do an 
alternative design.


Well, I found an alternative design not using opDispatch, not 
fundamentally dissimilar to what you suggested above, thanks for 
that, and it's not too uneconomical in its textual organization. 
I was hoping to avoid doing any of my own dispatching when 
inheritance would do it for me.






opDispatch doesn't play nice with inheritance

2018-11-15 Thread Carl Sturtivant via Digitalmars-d-learn

//Consider this:
import std.stdio;

void main() {
X obj = new Y;
writeln( obj._f() );
}

class Proxy {
X x;
this(X x) { this.x = x; }
string _f() { return "Proxy._f called"; }
}

class X {
auto opDispatch(string f, Args...)(Args args) {
Proxy p = new Proxy(this);
return mixin("p."~f~"(args)");
}
}

class Y : X {
string _f() { return "Y._f called"; }
}
//

Presumably the presence of obj._f()in main causes the compilation 
of a function _f() in the class X, yet the function _f() in Y 
that inherits it merely shadows it; the keyword override cannot 
be used for this function.


opDispatch is special in that it allows for functions to be added 
to a class or struct when undefined overtly but used elsewhere 
but it seems those functions sadly are final.


Can anything useful be done to remedy the situation?




Re: custom sorting of lists ?

2018-10-19 Thread Carl Sturtivant via Digitalmars-d-learn
On Friday, 19 October 2018 at 17:53:58 UTC, Stanislav Blinov 
wrote:
On Friday, 19 October 2018 at 17:40:59 UTC, Carl Sturtivant 
wrote:


If we imagine an Ordered Range being a finite Range of some 
kind with the additional property that its values are ordered 
(--- exact definition needed ---)...


There's already a SortedRange: 
https://dlang.org/phobos/std_range.html#.SortedRange


That's nice. So perhaps all this can be done in using the 
existing machinery in Phobos.




Re: custom sorting of lists ?

2018-10-19 Thread Carl Sturtivant via Digitalmars-d-learn
On Wednesday, 17 October 2018 at 19:02:00 UTC, Steven 
Schveighoffer wrote:

On 10/17/18 2:03 PM, Carl Sturtivant wrote:
On Monday, 15 October 2018 at 13:39:59 UTC, Steven 
Schveighoffer wrote:


But that's just the thing -- merge sort *does* depend on the 
container type. It requires the ability to rearrange the 
elements structurally, since you merge the sets of items 
together. This requires making another list from the original 
list, and ranges don't lend themselves to that.


One thing you *can* do is allocate an array beside the 
original container, and move things back and forth. But this 
is not required if you have a linked-list type which can 
simply be restructured without moving.


Doesn't this just mean a new special kind of range is needed 
to be defined?




I don't think it fits into range primitives. Basically, I need 
to rearrange one element from one place to another in O(1) time 
(and without actually moving/copying the data).


This really just is a linked-list special feature. One thing to 
note is that in a range of T, this move has nothing to do with 
the T.


-Steve


If we imagine an Ordered Range being a finite Range of some kind 
with the additional property that its values are ordered (--- 
exact definition needed ---). And work with Ranges of Ordered 
Ranges, can't we then sort by starting with a Range of single 
element Ranges (which are automatically ordered), and then 
pairwise merge repeatedly, i.e. get the next two elements (which 
are ordered ranges) and merge them & repeat, producing a Range of 
Ordered Ranges with half as many elements --- this is what I 
meant by pairwise merging --- and apply that pairwise merge 
repeatedly to the original range. I'm speculating intuitively, 
but it does look like there exists a possible extension of the 
notion of Range that would do the job.






Re: custom sorting of lists ?

2018-10-17 Thread Carl Sturtivant via Digitalmars-d-learn
On Monday, 15 October 2018 at 13:39:59 UTC, Steven Schveighoffer 
wrote:


But that's just the thing -- merge sort *does* depend on the 
container type. It requires the ability to rearrange the 
elements structurally, since you merge the sets of items 
together. This requires making another list from the original 
list, and ranges don't lend themselves to that.


One thing you *can* do is allocate an array beside the original 
container, and move things back and forth. But this is not 
required if you have a linked-list type which can simply be 
restructured without moving.


Doesn't this just mean a new special kind of range is needed to 
be defined?




std.process.pipeProcess stalls (linux)

2018-06-01 Thread Carl Sturtivant via Digitalmars-d-learn
A computationally intensive process run from the command line 
works fine, runs to completion after several minutes, writing a 
few hundred lines of text to standard output and creating, 
writing to and closing around 200 files of size around 20KB.


Now run from std.process.pipeProcess and periodically tested for 
completion with tryWait interleaved with sleep everything seems 
fine for a while. htop reveals that one core is running this at 
100% CPU, and the first 76 files appear one after another, but 
the 77th file is opened and nothing is written to it, and htop 
reveals that the CPU usage has dropped to zero, and yet the 
process is still running according to ps, and this continues 
indefinitely, no error message, no indication from tryWait that 
it is done. htop does not reveal at any point that memory use is 
even half of what is available.


Previously with similar processes that are a somewhat scaled back 
version of the one that fails as above, there's been no 
difference between what happened at the command line and what's 
happening here.


Any ideas or suggestions?



Re: Initialization of struct containing anonymous union

2017-08-14 Thread Carl Sturtivant via Digitalmars-d-learn
On Monday, 14 August 2017 at 15:11:35 UTC, Steven Schveighoffer 
wrote:

On 8/14/17 10:57 AM, Carl Sturtivant wrote:
On Monday, 14 August 2017 at 14:49:57 UTC, Steven 
Schveighoffer wrote:

On 8/14/17 10:36 AM, Carl Sturtivant wrote:
On Monday, 14 August 2017 at 14:24:40 UTC, Steven 
Schveighoffer wrote:


I think what the docs mean is that as soon as an anonymous 
union is present, you can't initialize anything further 
than the first union field.


I understood that, hence my remark that "this is not 
helpful".


OK. I thought you meant that the documentation is not helpful 
enough to understand what it means.




So it seems I am forced to assign explicitly to each 
member of the struct, an ugly process.


What is a nice way to solve this problem?


I think the only way to solve it is with a constructor:

this(int ival, double xval) { i = ival; x = xval; }


As I though I made clear, I don't want write assignments to 
each variable in a 50 or 100 member struct from a library 
when D could supply a better solution.


Sorry, I thought you meant to assign the fields manually 
outside an initializer function.


I can print out such a struct using writeln, but can find no 
way to use that text cleaned up in source code to create 
such a struct. Is D completely deficient here?


Hm... have you tried named field initializers?

mess m = { i: 99, x: 3.14};



I could do that, but again it would involve finding the 50 or 
100 names and writing text that looks quite like the text of 
an assignment except using colon instead of equals. So just as 
long and ugly.


Well, you only have to initialize the ones that aren't 
defaulted. So in some use cases, this is hugely beneficial.


But it seems in your case, you want to intialize everything 
explicitly (but only one member from each union).


Tried this, also works. Looks like you just have to name items 
after the unions (i.e. when you are skipping members). Ugly, 
but passable:


struct mess
{
union
{
int i;
string s;
}
double x;
int z;
}

mess s = {99, x: 3.14, 5};

-Steve


!
Agreed!


Re: Initialization of struct containing anonymous union

2017-08-14 Thread Carl Sturtivant via Digitalmars-d-learn
On Monday, 14 August 2017 at 14:49:57 UTC, Steven Schveighoffer 
wrote:

On 8/14/17 10:36 AM, Carl Sturtivant wrote:
On Monday, 14 August 2017 at 14:24:40 UTC, Steven 
Schveighoffer wrote:


I think what the docs mean is that as soon as an anonymous 
union is present, you can't initialize anything further than 
the first union field.


I understood that, hence my remark that "this is not helpful".


OK. I thought you meant that the documentation is not helpful 
enough to understand what it means.




So it seems I am forced to assign explicitly to each member 
of the struct, an ugly process.


What is a nice way to solve this problem?


I think the only way to solve it is with a constructor:

this(int ival, double xval) { i = ival; x = xval; }


As I though I made clear, I don't want write assignments to 
each variable in a 50 or 100 member struct from a library when 
D could supply a better solution.


Sorry, I thought you meant to assign the fields manually 
outside an initializer function.


I can print out such a struct using writeln, but can find no 
way to use that text cleaned up in source code to create such 
a struct. Is D completely deficient here?


Hm... have you tried named field initializers?

mess m = { i: 99, x: 3.14};



I could do that, but again it would involve finding the 50 or 100 
names and writing text that looks quite like the text of an 
assignment except using colon instead of equals. So just as long 
and ugly.




I believe you could generate a constructor given the 
introspection of the fields themselves. Probably would be messy 
though.


Probably worth investigating, though not handy when quickly 
writing a short one-off tool. Was hoping D would have a better 
way.





Re: Initialization of struct containing anonymous union

2017-08-14 Thread Carl Sturtivant via Digitalmars-d-learn
On Monday, 14 August 2017 at 14:24:40 UTC, Steven Schveighoffer 
wrote:


I think what the docs mean is that as soon as an anonymous 
union is present, you can't initialize anything further than 
the first union field.


I understood that, hence my remark that "this is not helpful".

So it seems I am forced to assign explicitly to each member of 
the struct, an ugly process.


What is a nice way to solve this problem?


I think the only way to solve it is with a constructor:

this(int ival, double xval) { i = ival; x = xval; }


As I though I made clear, I don't want write assignments to each 
variable in a 50 or 100 member struct from a library when D could 
supply a better solution. I can print out such a struct using 
writeln, but can find no way to use that text cleaned up in 
source code to create such a struct. Is D completely deficient 
here?




Initialization of struct containing anonymous union

2017-08-14 Thread Carl Sturtivant via Digitalmars-d-learn

  struct mess
  {
union
{
int i;
string s;
}
double x;
  }

How do I cleanly initialize this, assuming it's i that I want to 
give an overt value to?


The docs say "If there are anonymous unions in the struct, only 
the first member of the anonymous union can be initialized with a 
struct literal, and all subsequent non-overlapping fields are 
default initialized". This is not helpful.

https://dlang.org/spec/struct.html#struct-literal

The above is a toy example distilled from a real problem. The 
struct comes from a C library and is very long and contains 
several anonymous unions. The D declaration of the struct was 
made by someone else who made the library available to D.


I printed out such a struct returned by a call to the library, 
and wanted to create my own from scratch. But it seems that I 
can't just copy what writeln printed and edit it into an 
initialization analogous to


  mess m = { 99, 3.14 };

with the above, because I just get the analog of

Error: overlapping initialization for field i and s
Error: cannot implicitly convert expression (3.14) of type double 
to string


and the alternative more like what is printed by writeln,

  auto m = mess(99, 3.14);

produces a similar error message.

So it seems I am forced to assign explicitly to each member of 
the struct, an ugly process.


What is a nice way to solve this problem?




Re: subtlety or bug?

2017-05-10 Thread Carl Sturtivant via Digitalmars-d-learn
Aha, https://dlang.org/spec/struct.html#struct-destructor says 
that


An identity assignment overload is required for a struct if one 
or more of these conditions hold:


* it has a destructor

so this is the above condition coming into play.




subtlety or bug?

2017-05-10 Thread Carl Sturtivant via Digitalmars-d-learn

The following compiles and runs correctly.
https://forum.dlang.org/post/tzwsohkcqrkqotbwn...@forum.dlang.org

But if I add a destructor to the reference struct template as 
follows, it no longer compiles, and the complaints are not about 
the destructor.

```
~this()
{
ptr = null;
}
```
refsim.d(39): Error: generated function 
refsim.reference!int.reference.opAssign (reference!int p) is not 
callable using argument types (int)
refsim.d(42): Error: generated function 
refsim.reference!int.reference.opAssign (reference!int p) is not 
callable using argument types (int)


These are complaining about lines where reference!int variables 
are assigned integers.


What's going on?

Here's the code linked to above without the destructor that works.
```
struct reference(T)
{
T* ptr;
this(ref T x)
{
ptr = &x;
}
import std.exception : enforce;

ref T cnvrt() @property
{
enforce( ptr !is null);
return *ptr;
}
ref T cnvrt(T x) @property
{
enforce( ptr !is null);
return *ptr = x;
}
alias cnvrt this;
}

void main()
{
int i;
auto ri = reference!int(i);
auto ri2 = reference!int(ri);

assert(ri.ptr==ri2.ptr);

i = 99;
assert(i==ri && i==ri2 && ri==ri2);

ri = 100;
assert(i==ri && i==ri2 && ri==ri2);

ri2 = 101;
assert(i==ri && i==ri2 && ri==ri2);
}
```



Re: alias can't find symbol or can't use symbol

2017-05-06 Thread Carl Sturtivant via Digitalmars-d-learn

On Wednesday, 3 May 2017 at 09:04:07 UTC, Jonathan M Davis wrote:
I believe that the core problem is that an alias declaration 
just aliases a symbol - i.e. it just creates a new name for the 
symbol. And as far as I can tell,


alias n2 = x2.n;

is actually equivalent to

alias n2 = member.n;

You get exactly the same error message if that change is made. 
It's a bit like how you can call a static function with an 
object rather than the struct/class(e.g. s.foo() instead of 
S.foo()). Similarly, if you turn n into a member function, then 
you get an error like


q.d(20): Error: this for n needs to be type member not type 
outer


It's just aliasing the function, not creating a delegate or 
doing a syntactic conversion. If it _were_ doing a syntactic 
conversion and just making it so that everywhere you see n2, it 
got changed to x.n, then I could see code like


outer o;
o.n2 = 5;

working. But that's not how alias declarations work. They just 
create a new name for the symbol in the scope that they're 
declared. So, the symbol isn't tied to a particular instance, 
and you get the problem that you're having.


The following works with
outer2 o;
o.n2 = 5;
so it's not static, i.e. n2 is tied to the instance here.

struct outer2
{
int n;
alias n2 = n;
}

So it seems reasonable to have better semantics for an embedded 
struct with alias_this.





Re: alias can't find symbol or can't use symbol

2017-05-04 Thread Carl Sturtivant via Digitalmars-d-learn

On Wednesday, 3 May 2017 at 09:04:07 UTC, Jonathan M Davis wrote:


I believe that the core problem is that an alias declaration 
just aliases a symbol - i.e. it just creates a new name for the 
symbol. And as far as I can tell,


alias n2 = x2.n;

is actually equivalent to

alias n2 = member.n;

You get exactly the same error message if that change is made. 
It's a bit like how you can call a static function with an 
object rather than the struct/class(e.g. s.foo() instead of 
S.foo()). Similarly, if you turn n into a member function, then 
you get an error like


q.d(20): Error: this for n needs to be type member not type 
outer


It's just aliasing the function, not creating a delegate or 
doing a syntactic conversion. If it _were_ doing a syntactic 
conversion and just making it so that everywhere you see n2, it 
got changed to x.n, then I could see code like


outer o;
o.n2 = 5;

working. But that's not how alias declarations work. They just 
create a new name for the symbol in the scope that they're 
declared. So, the symbol isn't tied to a particular instance, 
and you get the problem that you're having.


alias this is a bit different, because it isn't really aliasing 
the symbol - rather it's telling the compiler about an implicit 
conversion. So, that arguably confuses things a  bit, but for 
your example to work, normal alias declarations would need to 
do more than create a new name for a symbol, and as I 
understand it, they don't.


Now, I totally agree that it would be nice if your example 
would work, and I think that I've run into this problem before 
in my own code, but aliases would have to work a bit 
differently than they curently do for it to work. It seems like 
a reasonable enhancement request to me, but I'm not sure what 
Walter's take on it would be. He has a tendancy to see things 
how the compiler would in cases like this and not necessarily 
how a typical programmer would, so it wouldn't surprise me if 
he's reaction were that of course it wouldn't work, but I don't 
know. It's often the case that what the programmer thinks is 
intuitive doesn't really jive with how the language actually 
works.


Thanks, that was enlightening. That said, if alias this really 
did bring n into the outer scope in the specific case when it's a 
variable in an embedded struct then `alias n2 = n` in the outer 
scope would work in the ordinary way. After all,


struct fakeOuter
{
  int n;
  alias n2 = n;
}

void main()
{
  fakeOuter o;
  o.n2 = 5;
}

compiles and runs fine. And presumably as it's a struct being 
embedded here


struct member
{
int n;
}

struct outer
{
member x;
alias x this;
//alias n2 = n;
}

the binary layouts of fakeOuter and outer are the same, so the 
rename is harmless because it has a simple interpretation in 
regular D without `alias this`.






Re: alias can't find symbol or can't use symbol

2017-04-30 Thread Carl Sturtivant via Digitalmars-d-learn

On Sunday, 30 April 2017 at 02:19:29 UTC, bauss wrote:

What exactly did you expect here?

'n' is not in the scope of 'outer'.

'n' is in the scope of 'member'.

Of course it works with 'x.n' since 'x' points to the 'member' 
declared inside 'outer'.


I mean it would have worked with classes, but structs are 
different does not have any type of actual inheritance, which 
is what you're trying to achieve.


```
class member {
int n;
}

class outer : member {
alias n2 = n; // Ok ...
}
```


It did NOT work with x.n as I asserted. And `alias x this` brings 
n into the scope of outer. So your reply makes no sense.




alias can't find symbol or can't use symbol

2017-04-29 Thread Carl Sturtivant via Digitalmars-d-learn

Consider the following.

struct member
{
int n;
}

struct outer
{
member x;
alias x this;
alias n2 = n;
}

This does not compile: alias n2 = n;
Error: undefined identifier 'n'

On the other hand if change that into
alias n2 = x.n;
then it does compile.

void main()
{
outer o;
o.n2 = 5;
}

Now this code doesn't compile: o.n2 = 5;
Error: need 'this' for 'n' of type 'int'

Given that one struct inside another is a static situation, this 
seems unnecessarily strict. It's getting in the way of some name 
management with `alias this`. What's the rationale here?






Re: std.digest toHexString

2017-03-16 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 16 March 2017 at 18:51:45 UTC, Adam D. Ruppe wrote:
Phobos could have been written to avoid this problem too, 
there's a few solutions that work, but right now, using the 
standard library in a way people expect to work will be 
silently disastrous.


Yes, and as an outsider I find this, well, disconcerting. No 
complaint from the compiler about assignment to string of the 
result of a library function call should have produced a string 
with the obvious semantics.


Having read this thread I have formed a conclusion.

Implicitly slicing rvalue arrays is too much like implicitly 
taking the address of an rvalue.


There's an explicit postfix operator [] to do that, and if there 
was no implicit slicing, I'd at least know where slicing is 
occurring and I wouldn't use the slice of a temporary beyond its 
lifetime.


Now a function with a slice parameter could not be called with an 
rvalue array parameter without putting an explicit slice operator 
in at the point of call.


But writing a function like that is just a way to regard rvalue 
arrays of different sizes based upon the same type as being the 
same type, when they are not. They are distinct types. And so a 
template could take care of that minor syntactic problem if so 
desired, with one instantiation for each rvalue array type (i.e. 
size), with a ref parameter to avoid copying.


I see every reason to remove implicit slicing of rvalue arrays.

Trying to keep it available sometimes is a complex endeavor, and 
the rules will be lengthy, and consequently have more 
complications to explain to people joining use of D, and for 
what? There's almost nothing to gain. This would be a mistake. D 
is already very large.


If I didn't know what my general confidence level in D was for 
other reasons, this incident could well have driven me away. The 
standard library compiled completely unexpectedly insane and 
unsafe semantics when I just called a simple-looking function. 
This sort of thing is undoubtedly bringing D into disrepute with 
some people here and there, people just trying it out to solve a 
problem.






Re: std.digest toHexString

2017-03-16 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 16 March 2017 at 17:20:45 UTC, H. S. Teoh wrote:
I'm not convinced casting static array to immutable is OK. 
Check this out:


import std.stdio;

char[32] func() {
char[32] staticArr = "A123456789abcdefB123456789abcdef";
return staticArr; // OK, by-value return
}

string gunk() {
	string x = func(); // implicit conversion char[32] -> 
string

writeln(x.ptr);
writeln(x); // prints "A123456789abcdefB123456789abcdef"
return x;
}

void main() {
auto s = gunk();
writeln(s.ptr); // prints same address as in gunk()
writeln(s); // prints corrupted string
}

Run this code and you'll see that s.ptr has the same address as 
x.ptr, and that x.ptr is the address of a local variable. This 
is blatantly wrong.


Filed a new issue for this:

https://issues.dlang.org/show_bug.cgi?id=17261


Exactly, if there was a variable of type char[32] on the right 
hand side of

string x = func();
instead of the call of func, then the compiler would complain. So 
this is a bug.






Re: std.digest toHexString

2017-03-16 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 16 March 2017 at 17:18:30 UTC, Adam D. Ruppe wrote:
On Thursday, 16 March 2017 at 17:12:08 UTC, Carl Sturtivant 
wrote:

I did that, and it made no difference. :(


wait a minute i just realized:

toHexString.d(11) in the error message

You named the file toHexString which means the *module* will be 
named toHexString by default...


OK, right!




Re: std.digest toHexString

2017-03-16 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 16 March 2017 at 16:59:40 UTC, Adam D. Ruppe wrote:
Yet the documentation says there's a toHexString that returns 
a string.


Yes, indeed, it returns a string if it is passed a dynamic 
array.


Ah, that's the distinction, should have noticed.

Remember though, like I warned on my doc fork, overload 
resolution NEVER looks at the left hand side of the equation, 
it is always done on arguments alone.


The stupid auto return stuff Phobos loves so much obscures it, 
but md5Of returns a ubyte[16].


That calls the first overload, the one that returns char[num*2]


OK, but if I try to do this,

char[2] u;
string s = u;

the compiler will complain: Error: cannot implicitly convert 
expression (u) of type char[2] to string. So why does it allow 
the template instantiation  of return type char[num*2] in place 
of u above?





Re: std.digest toHexString

2017-03-16 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 16 March 2017 at 17:01:56 UTC, Adam D. Ruppe wrote:
On Thursday, 16 March 2017 at 16:56:11 UTC, Carl Sturtivant 
wrote:
"toHexString.d(11): Error: function expected before (), not 
module toHexString of type void"

Module???


huh idk.

use my search engine btw!  http://dpldocs.info/toHexString

it is in `std.digest.digest` but that should be publicly 
imported.


I did that, and it made no difference. :(



Re: std.digest toHexString

2017-03-16 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 16 March 2017 at 16:21:08 UTC, Adam D. Ruppe wrote:
If I replace md5Of(arg).toHexString() with 
toHexString(md5Of(arg))


That works for me though... maybe it is just a version mismatch 
or something, since toHexString is in a different module than 
md5of.


I have this problem on Linux and Windows, at 64 bits on the 
former, and 32 on the latter, with simple clean installations of 
dmd 2.073.2 on Linux, 2.073.3 on Windows. Same error message.
"toHexString.d(11): Error: function expected before (), not 
module toHexString of type void"

Module???



Re: std.digest toHexString

2017-03-16 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 16 March 2017 at 16:21:08 UTC, Adam D. Ruppe wrote:
On Thursday, 16 March 2017 at 16:13:33 UTC, Carl Sturtivant 
wrote:

string ans = md5Of(arg).toHexString();


That is a major D design flaw biting you the same way it has 
bitten so many others.


See the red box in my documentation fork:

http://dpldocs.info/experimental-docs/std.digest.digest.toHexString.2.html

toHexString returns a static array... on the stack. Then the 
stupid language not only implicitly casts it to immutable, it 
also implicitly slices it, giving you a reference to mutable, 
temporary data pretending to be permanent, immutable data.


Silently  cast to immutable without 
copying!??!! This is so wrong.


Yet the documentation says there's a toHexString that returns a 
string.

http://dlang.org/phobos/std_digest_digest.html#.toHexString
I don't understand the overload resolution implied at this link. 
How is a toHexString selected in

string ans = md5Of(arg).toHexString();
?




std.digest toHexString

2017-03-16 Thread Carl Sturtivant via Digitalmars-d-learn

What's going on here?
```
import std.digest.md, std.stdio;

void main() {
string ans = hex("qwertyuiop");
writeln(ans);
}

string hex(string arg) {
string ans = md5Of(arg).toHexString();
writeln(ans);
return ans;
}
```
This compiles, and when run writes out corrupt nonsense from the 
writeln in main, while just before that writing out 
6EEA9B7EF19179A06954EDD0F6C05CEB from the function hex.


If I replace md5Of(arg).toHexString() with 
toHexString(md5Of(arg)) it won't compile, claiming that 
"toHexString.d(11): Error: function expected before (), not 
module toHexString of type void". Yet the examples here

http://dlang.org/phobos/std_digest_md.html
use toHexString freely in this way. I thought I was using 
toHexString by UFCS, in the earlier example, but this appears to 
be untrue.


The return from the function hex above somehow corrupts the 
string returned, suggesting deallocation is occurring in some 
fashion. So I replaced md5Of(arg).toHexString() with 
md5Of(arg).toHexString().dup and the problem vanished. Now 
6EEA9B7EF19179A06954EDD0F6C05CEB is printed out twice.




Part of D available to run at compile time

2016-03-29 Thread Carl Sturtivant via Digitalmars-d-learn


is there documentation on which parts of D are available to 
compile time execution?




link to C++ function in a namespace whose name is a D keyword

2016-01-06 Thread Carl Sturtivant via Digitalmars-d-learn

Hello,

From D I want to call e.g.

/* C++ prototype */
namespace ns {
int try(int x);
}

without writing a C or C++ wrapper.

Presumably the following D doesn't work, because it doesn't 
mangle the name as if it's in the namespace ns.


pragma(mangle, "try") extern(C++, ns) int try_(int x);

So how to I get correct mangling here?



Re: link to C function whose name is a D keyword

2016-01-06 Thread Carl Sturtivant via Digitalmars-d-learn

On Wednesday, 6 January 2016 at 15:42:34 UTC, Adam D. Ruppe wrote:
On Wednesday, 6 January 2016 at 15:41:27 UTC, Carl Sturtivant 
wrote:

//D that doesn't work:
extern(C) int try(int x);


Try:

pragma(mangle, "try")
extern(C) int try_(int x);

then call it with the udnerscore in D, the linker should tie it 
up thanks to the pragma.


Very handy! Thank you.




link to C function whose name is a D keyword

2016-01-06 Thread Carl Sturtivant via Digitalmars-d-learn

Hello,

Is there a way from D to do this, without writing a C wrapper?

e.g. I want to call a C function named 'try'.

/* C prototype */
int try(int x);

//D that doesn't work:
extern(C) int try(int x);




Re: DFLAGS ignored. How to get a dmd installation on windows that is 64 bit only

2015-11-22 Thread Carl Sturtivant via Digitalmars-d-learn


If you must force dmd to be only 64bit, use sc.ini file to do 
so and not rely on your environment variables.


OK, why?
(This does work, so thank you.)


Also why do you not want 32-bit support?
It's not like it won't work on a 64bit computer, it will.


I've used 32-bit D and DMC a lot on real projects, so I am aware 
of this. I just want to tinker with the installation on a machine 
I use for that sort of thing, without worrying about the 32-bit 
configuration at all, and with no possibility of executing 32-bit 
tools.




DFLAGS ignored. How to get a dmd installation on windows that is 64 bit only

2015-11-21 Thread Carl Sturtivant via Digitalmars-d-learn
The docs for dmd for windows say that the DFLAGS environment 
variable's value will be appended to the dmd command line. I 
tried this with -m64 as the value and this is ignored.

http://dlang.org/dmd-windows.html#environment

More generally, is there a standard rearrangement of files and 
environment variables so that all compilation and linking is 64 
bit, and 32-bit stuff is simply not there?






Re: cast(T) documentation

2015-11-05 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 5 November 2015 at 18:52:05 UTC, Ali Çehreli wrote:

On 11/05/2015 07:51 AM, Carl Sturtivant wrote:

Hello,

Is cast(T) documented all in one place somewhere? I'd like to 
understand

exactly what it does and does not do.



This is what I can find:

  http://dlang.org/expression.html#CastExpression

Ali


Hello Ali, I probably should have found that! Thanks.


cast(T) documentation

2015-11-05 Thread Carl Sturtivant via Digitalmars-d-learn

Hello,

Is cast(T) documented all in one place somewhere? I'd like to 
understand exactly what it does and does not do.





trouble compiling Fiber example code from docs dmd linux v2.067.1

2015-08-06 Thread Carl Sturtivant via Digitalmars-d-learn

I took the example code from here,
http://dlang.org/phobos/core_thread.html#.Fiber
and wrapped the statements at the bottom inside main() and put 
import core.thread and std.stdio at the top, and the compiler 
gave me the following.


/usr/include/dmd/druntime/import/core/thread.d(3894): Error: 
static variable PAGESIZE cannot be read at compile time
fiberexample.d(8):called from here: super.this(&this.run, 
PAGESIZE * 4LU)
/usr/include/dmd/druntime/import/core/thread.d(3871): Error: 
static variable PAGESIZE cannot be read at compile time


Help anyone?



Re: Seems core.thread.Fiber is broken dmd windows 64-bit build

2015-03-09 Thread Carl Sturtivant via Digitalmars-d-learn

http://forum.dlang.org/thread/md5kq0$8au$1...@digitalmars.com


Got a working build at 64 bits using the 2.067 beta 3.
Delighted.


Re: Seems core.thread.Fiber is broken dmd windows 64-bit build

2015-03-09 Thread Carl Sturtivant via Digitalmars-d-learn
IIRC there are some fixes to the Win64 context switching code 
in the 2.067 or master druntime. You might want to try those 
first before spending more time tracking this down.


Great, and thanks.


Re: Seems core.thread.Fiber is broken dmd windows 64-bit build

2015-03-09 Thread Carl Sturtivant via Digitalmars-d-learn

On Monday, 9 March 2015 at 17:00:38 UTC, Jacques Müller wrote:

With the newest beta everything seems to work fine.
http://forum.dlang.org/thread/md5kq0$8au$1...@digitalmars.com


That's great news! Thank you.


Re: Seems core.thread.Fiber is broken dmd windows 64-bit build

2015-03-09 Thread Carl Sturtivant via Digitalmars-d-learn


I can reproduce this issue with dmd 2.066.1,
please go forward and open a issue on https://issues.dlang.org/

Kind Regards
Benjamin Thaut


Thank you; will do.


Re: Seems core.thread.Fiber is broken dmd windows 64-bit build

2015-03-09 Thread Carl Sturtivant via Digitalmars-d-learn
Please confirm or deny that this is a real bug, as its getting in 
the way of a genuine project. How should I proceed?


I'm working on a 64-bit Windows port of the following.
http://www.cs.arizona.edu/icon/
Here's the 32-bit Windows port.
http://www.cs.arizona.edu/icon/v95w.htm

Among other things I'm using D to implement Icon's coexpressions 
portably using core.thread.Fiber which works fine at 32 bits. 
They are implemented using pthreads on other platforms, though 
historically there used to be a platform dependent assembly code 
context switch, close to the way that core.thread.Fiber is 
implemented. The Fiber implementation is 20 times faster at 32 
bits.


Seems core.thread.Fiber is broken dmd windows 64-bit build

2015-03-08 Thread Carl Sturtivant via Digitalmars-d-learn


The following crashes on Windows 7 sp1 64-bit edition when build 
at 64 bits with dmd and the Microsoft linker that comes with 
Windows SDK 7.1 (i.e. MSVC 2010 linker). I've had no trouble with 
other D code when using that arrangement, though I have not used 
threads. When built at 32 bits with dmd and optlink it runs fine.

==
import core.thread, std.stdio;

void main() {
writefln( "A pointer is %d bytes", (void*).sizeof);
void f1() {
writeln( 1);
Fiber.yield();
writeln( 3);
}
auto fiber = new Fiber( &f1);
fiber.call();
writeln( 2);
fiber.call();
writeln( 4);
}
===
The 64 bit version outputs 1 and crashes when yield is executed. 
Other tests reveal that yield is the problem.


Should I be doing something special with linkage so this works? 
What is going on?


Re: core.thread.Fiber --- runtime stack overflow unlike goroutines

2014-08-15 Thread Carl Sturtivant via Digitalmars-d-learn

On Friday, 15 August 2014 at 20:11:43 UTC, Carl Sturtivant wrote:

On Friday, 15 August 2014 at 08:41:30 UTC, Kagamin wrote:
On Thursday, 14 August 2014 at 07:46:29 UTC, Carl Sturtivant 
wrote:
The default size of the runtime stack for a Fiber is 
4*PAGESIZE which is very small, and a quick test shows that a 
Fiber suffers a stack overflow that doesn't lead to a clean 
termination when this limit is exceeded.


Pass a bigger stack size to the Fiber constructor?


No good if the stack size needed depends dynamically on the 
computation in that Fiber.


Should have read further down the thread --- you're right as the 
memory is in effect merely reserved virtual memory and isn't 
actually allocated.


Re: core.thread.Fiber --- runtime stack overflow unlike goroutines

2014-08-15 Thread Carl Sturtivant via Digitalmars-d-learn

On Friday, 15 August 2014 at 15:40:35 UTC, Sean Kelly wrote:

On Friday, 15 August 2014 at 15:25:23 UTC, Dicebot wrote:


No, I was referring to the proposal to supply bigger stack 
size to Fiber constructor - AFAIR it currently does allocate 
that memory eagerly (and does not use any OS CoW tools), 
doesn't it?


I thought it did, but apparently the behavior of VirtualAlloc 
and mmap (which Fiber uses to allocate the stack) simply 
reserves the range and then commits it lazily, even though what 
you've told it to do is allocate the memory.  This is really 
great news since it means that no code changes will be required 
to do the thing I wanted to do anyway.


Just read this after posting earlier replies! Very exciting.

I'll be doing some experiments to see how this works out.

What about at 32-bits?


Re: core.thread.Fiber --- runtime stack overflow unlike goroutines

2014-08-15 Thread Carl Sturtivant via Digitalmars-d-learn

On Friday, 15 August 2014 at 08:41:30 UTC, Kagamin wrote:
On Thursday, 14 August 2014 at 07:46:29 UTC, Carl Sturtivant 
wrote:
The default size of the runtime stack for a Fiber is 
4*PAGESIZE which is very small, and a quick test shows that a 
Fiber suffers a stack overflow that doesn't lead to a clean 
termination when this limit is exceeded.


Pass a bigger stack size to the Fiber constructor?


No good if the stack size needed depends dynamically on the 
computation in that Fiber.


Re: core.thread.Fiber --- runtime stack overflow unlike goroutines

2014-08-15 Thread Carl Sturtivant via Digitalmars-d-learn

On Thursday, 14 August 2014 at 18:52:00 UTC, Sean Kelly wrote:
On 64 bit, reserve a huge chunk of memory, set a SEGV handler 
and commit more as needed. Basically how kernel thread stacks 
work. I've been meaning to do this but haven't gotten around to 
it yet.


Very nice; the hardware VM machinery takes care of it and there's 
only overhead when overflow occurs. D's Fibers will really be 
something remarkable for user-space with this facility.


core.thread.Fiber --- runtime stack overflow unlike goroutines

2014-08-14 Thread Carl Sturtivant via Digitalmars-d-learn


The default size of the runtime stack for a Fiber is 4*PAGESIZE 
which is very small, and a quick test shows that a Fiber suffers 
a stack overflow that doesn't lead to a clean termination when 
this limit is exceeded.


This makes it difficult to simulate deterministic alternation 
where the stack size needed is unpredictable because complex 
deterministic computations are going on inside Fibers.


In contrast, the Go programming language's goroutines can extend 
their stacks as needed at runtime, and so can be used to simulate 
deterministic alternation without this limitation, and yet be 
initially executed with each having only a small stack size.


There seems to be a claim that all that's needed to add 
D-routines (goroutines for D) is a scheduler and a Channel type, 
on top of Fiber.

http://forum.dlang.org/thread/lphnen$1ml7$1...@digitalmars.com
See the initial post, point 7., as well as supporting remarks in 
later replies.


Am I missing something? Is there a clean and simple way to get 
Fiber to no longer suffer a stack overflow when implementing 
D-routines?


Re: D may disappoint in the presence of an alien Garbage Collector?

2014-07-29 Thread Carl Sturtivant via Digitalmars-d-learn

On Monday, 28 July 2014 at 20:52:01 UTC, Anton wrote:

On Monday, 28 July 2014 at 19:57:38 UTC, Carl Sturtivant wrote:
Suppose I want to use D as a system programming language to 
work with a library of functions written in another language, 
operating on dynamically typed data that has its own garbage 
collector, such as an algebra system or the virtual machine of 
a dynamically typed scripting language viewed as a library of 
operations on its own data type. For concreteness, suppose the 
library is written in C. (More generally, the data need not 
restricted to the kind above, but for concreteness, make that 
supposition.)


Data in such a system is usually a (possibly elaborate) tagged 
union, that is essentially a struct consisting of (say) two 
words, the first indicating the type and perhaps containing 
some bits that indicate other attributes, and the second 
containing the data, which may be held directly or indirectly. 
Call this a Descriptor.


Descriptors are small, so it's natural to want them held by 
value and not allocated on the heap (either D's or the 
library's) unless they are a part of a bigger structure that 
naturally resides there. And it's natural to want them to 
behave like values when passed as parameters or assigned. This 
usually fits in with the sort of heterogeneous copy semantics 
of such a library, where some of the dynamic types are 
implicitly reference types and others are not.


The trouble is that the library's alien GC needs to be made 
aware of each Descriptor when it appears and when it 
disappears, so that a call of a library function that 
allocates storage doesn't trigger a garbage collection that 
vacuums up library allocated storage that a D Descriptor 
points to, or fails to adjust a pointer inside a D descriptor 
when it moves the corresponding data, or worse, follows a 
garbage pointer from an invalid D Descriptor that's gone out 
of scope. This requirement applies to local variables, 
parameters and temporaries, as well as to other situations, 
like D arrays of Descriptors that are D-heap allocated. Ignore 
the latter kind of occasion for now.


Abstract the process of informing the GC of a Descriptor's 
existence as a Protect operation, and that it will be out of 
scope as an Unprotect operation. Protect and Unprotect 
naturally need the address of the storage holding the relevant 
Descriptor.


In a nutshell, the natural requirement when interfacing to 
such a library is to add Descriptor as a new value type in D 
along the lines described above, with a definition such that 
Protect and Unprotect operations are compiled to be performed 
automatically at the appropriate junctures so that the user of 
the library can forget about garbage collection to the usual 
extent.


How can this requirement be fulfilled?


Suppose I want to do system programming...Would I choose the 
option with a GC ?
Just get off. The GC is just such a fagot. People are smart 
enough to manage memory.


It's the library to interface to that has its own GC, not my 
code. I just need to use D's system programming capabilities to 
work around the library's nasty GC so my data used by my calls to 
that library isn't trashed, and to do that efficiently and 
transparently. A system programming language should be able to 
efficiently interface to anything, right?




Re: D may disappoint in the presence of an alien Garbage Collector?

2014-07-29 Thread Carl Sturtivant via Digitalmars-d-learn

On Monday, 28 July 2014 at 21:33:54 UTC, Rene Zwanenburg wrote:


If I understand you correctly, an easy way is to use RefCounted 
with a simple wrapper. Something like this:


// Descriptor defined by the external library
struct DescriptorImpl
{
  size_t type;
  void* data;
}

// Tiny wrapper telling the alien GC of the existence of this 
reference

private struct DescriptorWrapper
{
  DescriptorImpl descriptor;
  alias descriptor this;

  @disable this();

  this(DescriptorImpl desc)
  {
// Make alien GC aware of this reference
  }

 ~this()
  {
// Make alien GC aware this reference is no longer valid
  }
}

// This is the type you will be working with on the D side
alias Descriptor = RefCounted!DescriptorWrapper;


Just read RefCounted definition here,
http://dlang.org/phobos/std_typecons.html#.RefCounted
and it heap allocates its object, so your response above does not 
stack allocate the basic type that you call DescriptorWrapper, 
and is not a solution to the problem as stated.


If there was no alien GC, but everything else was the same, heap 
allocation of something containing a DescriptorImpl would be 
unnecessary. Now achieve the same with the alien GC present 
without an extra layer of indirection and heap allocation --- 
this is the essence of my question.




Re: Linux Dynamic Loading of shared libraries

2014-07-29 Thread Carl Sturtivant via Digitalmars-d-learn

Can't retrieve the archive from that URL.
britseyeview.com/plugin101.tar.bz2
Interested, so can you please fix?

On Monday, 10 March 2014 at 11:59:20 UTC, Steve Teale wrote:

On Sunday, 9 March 2014 at 12:07:22 UTC, Steve Teale wrote:

Now suppose that my D shared library contains a class, rather 
that just module ctors/dtors, how do I go about creating an 
instance of that class and using its methods?


After wandering down several dead-end paths, and help from 
other contributors, I have finally come up with something that 
looks like the basis of a plugin pattern for Linux DMD using 
shared objects (.so files). This is somewhat long for a forum 
post. You can download this readme and the associated files 
from britseyeview.com/plugin101.tar.bz2


To get started, you need a base class that provides 
declarations for all functions that the plugin will be allowed 
to use externally. Why base class, and not interface? Well I 
guess because interfaces don't provide any information about 
data. If you create a shared library based on an interface, 
then all the shared object methods that reference data in the 
class that implements the interface fail miserably. I'm sure 
someone will explain why - probably some obvious thing I have 
overlooked.


OK, so my base class is:

module plugin;

class Plugin
{
   int n;
   this(int _n) { n = _n; }

   int foo() { return int.min; }
   void bar() {}
}


The class that implements this base in the shared library is:

module exta;
import plugin;
import std.stdio;
import std.math;

class ExtA: Plugin
{
   double d;
   this(int n) { super(n); d = PI; }

   override int foo() { return ++n; }
   override void bar() { writefln("Done my thing (%f)", d); }
}

Plugin getInstance(int n)
{
   return new ExtA(n);
}

shared static this() {
  writeln("exta.so shared static this");
}

shared static ~this() {
  writeln("exta.so shared static ~this");
}

The module ctor/dtor are included because that has become 
conventional in discussions about dynamic loading. Otherwise, 
the so has the class implementation - ExtA, and a shared method 
to create an instance of same. It includes references to 
methods in Phobos.


The test program is as follows:

module main;
import core.runtime;
import std.stdio;
import plugin;

extern(C) void* dlsym(void*, const char*);

alias Plugin function(int) pfi;

Plugin getPlugin(string name)
{
   void* lib = Runtime.loadLibrary(name~".so");
   if (lib is null)
   {
  writeln("failed to load plugin shared object");
  return null;
   }

   void* vp = dlsym(lib, 
"_D4exta11getInstanceFiZC6plugin6Plugin\0".ptr);

   if (vp is null)
   {
  writeln("plugin creator function not found");
  return null;
   }
   pfi f = cast(pfi) vp;
   Plugin x = f(42);
   if (x is null)
   {
  writeln("creation of plugin failed");
  return null;
   }
   return x;
}

void main()
{
   Plugin x = getPlugin("exta");
   int n = x.foo();
   writefln("n = %d", n);
   x.bar();
}

The long symbol name used in the dlsym() call is of course from 
the .map file generated when the .so file is created


These can be built using the following primitive makefile, 
whose main purpose is to spell out the required compiler flags:


main :
dmd -c plugin.d
dmd -c -shared -fPIC exta.d
dmd exta.o -shared -defaultlib=libphobos2.so -map
dmd -c main.d
dmd main.o plugin.o -L-ldl -defaultlib=libphobos2.so -L-rpath=.

This assumes that the plugins will be in the same directory as 
the executable (rpath=.).


Note that there is no call to Runtime.unloadLibrary(). The 
assumption her is that once the plugin has been loaded it will 
be there for the duration of the program. If you want to unload 
it you'll probably have to make sure the plugin object is 
purged from memory first, and I have not discovered how to do 
that yet ;=(


Steve




  1   2   >