Spec for the ‘locality’ parameter to the LDC and GDC builtin magic functions for accessing special CPU prefetch instructions

2023-08-19 Thread Cecil Ward via Digitalmars-d-learn



I’m trying to write a cross-platform function that gives access 
to the CPU’s prefetch instructions such as x86 
prefetch0/1/2/prefetchnta and AAarch64 too. I’ve found that the 
GDC and LDC compilers provide builtin magic functions for this, 
and are what I need. I am trying to put together a plain-English 
detailed spec for the respective builtin magic functions.


My questions:

Q1) I need to compare the spec for the GCC and LDC builtin magic 
functions’ "locality" parameter. Can anyone tell me if GDC and 
LDC have kept mutual compatibility here?


Q2) Could someone help me turn the GCC and LDC specs into english 
regarding the locality parameter ? - see (2) and (4) below.


Q3) Does the locality parameter determine which _level_ of the 
data cache hierarchy data is fetched into? Or is it always 
fetched into L1 data cache and the outer ones, and this parameter 
affects caches’ _future behaviour_?


Q3) Will these magic builtins work on AAarch64?

Here’s what I’ve found so far

1. GCC builtin published by the D runtime:
import gcc.simd : 
prefetch;

prefetch!( rw, locality )( p );

   2. GCC: builtin_prefetch (const void *addr, ...) ¶
“This function is used to minimize cache-miss latency by moving 
data into a cache before it is accessed. You can insert calls to 
__builtin_prefetch into code for which you know addresses of data 
in memory that is likely to be accessed soon. If the target 
supports them, data prefetch instructions are generated. If the 
prefetch is done early enough before the access then the data 
will be in the cache by the time it is accessed.
The value of addr is the address of the memory to prefetch. There 
are two optional arguments, rw and locality. The value of rw is a 
compile-time constant one or zero; one means that the prefetch is 
preparing for a write to the memory address and zero, the 
default, means that the prefetch is preparing for a read. The 
value locality must be a compile-time constant integer between 
zero and three. A value of zero means that the data has no 
temporal locality, so it need not be left in the cache after the 
access. A value of three means that the data has a high degree of 
temporal locality and should be left in all levels of cache 
possible. Values of one and two mean, respectively, a low or 
moderate degree of temporal locality. The default is three.”


3. declare void @llvm.prefetch(ptr , i32 , i32 
, i32 


4. Regarding llvm.prefetch() I found the following spec:
“rw is the specifier determining if the fetch should be for a 
read (0) or write (1), and locality is a temporal locality 
specifier ranging from (0) - no locality, to (3) - extremely 
local keep in cache. The cache type specifies whether the 
prefetch is performed on the data (1) or instruction (0) cache. 
The rw, locality and cache type arguments must be constant 
integers.”


5. I also found this snippet 
https://dlang.org/phobos/core_builtins.html - which is great for 
the syntax of the call to the LDC builtin, but the call for GDC 
is no good as it lacks the parameters that I want. This D runtime 
routine might benefit from accepting all the parameters that 
GCC’s prefetch builtin takes.


Many thanks in advance.



Test post - please ignore

2023-08-13 Thread Cecil Ward via Digitalmars-d-learn
I have been getting error messages when I try to post to the 
forum. This is just a test, so please ignore.


Setting up a final switch from a list

2023-08-02 Thread Cecil Ward via Digitalmars-d-learn
Am I right in thinking that final switch can be used to check 
that all the elements in an enum are handled in cases? Thinking 
that this is a worthwhile safety check, I’d like to convert an 
existing list into an enum for use in a final switch. I have an 
existing list which I use elsewhere,

   enum terminators = [ '%', ':', '?' ];

I pass that to some routine. I am wondering how to safely create 
either an enum with values or have the enum with values declared 
first and then create the list from it. That is, maybe start the 
other way around

 enum terminators_t = { percent = '%', colon = ':', qmark = '?' };
and then automatically generate the list from that. The idea is 
to avoid duplication in the array list and enum value list, so 
that if I ever add one, I will not be able to update the other to 
match.


Any suggestions? I need some good compile-time stuff. It doesn’t 
matter which direction we go in, from one to the other, but my 
money is on the all-values enum generating the array list.


Re: Anyone help me with a stack dump?

2023-07-31 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 31 July 2023 at 14:38:52 UTC, ryuukk_ wrote:

Your problem lies at line 1541

You can use `ddemangle` executable to make mangled names 
readable, i don't know if it comes with the compiler


```
_platform_memmove
pure nothrow ref @trusted wchar[] 
core.internal.array.appending._d_arrayappendT!(wchar[], 
char)._d_arrayappendT(scope return ref wchar[], scope wchar[])
void 
asm_parse.AsmTransformTemplate!(wchar).__unittest_L1541_C1_1()

asm_parse.__unittest
asm_parse.__unittest
asm_parse.__unittest
asm_parse.__unittest
int 
core.runtime.runModuleUnitTests().__foreachbody6(object.ModuleInfo*)
int rt.minfo.moduleinfos_apply(scope int 
delegate(immutable(object.ModuleInfo*))).__foreachbody2(ref 
rt.sections_elf_shared.DSO)
int rt.sections_elf_shared.DSO.opApply(scope int delegate(ref 
rt.sections_elf_shared.DSO))
int rt.minfo.moduleinfos_apply(scope int 
delegate(immutable(object.ModuleInfo*)))
int object.ModuleInfo.opApply(scope int 
delegate(object.ModuleInfo*))

runModuleUnitTests
void rt.dmain2._d_run_main2(char[][], ulong, extern (C) int 
function(char[][])*).runAll()

_d_run_main2
_d_run_main
start
```


Thank you all for your help. In the real code I have a struct 
(object) in the heap but in the unittests I first of all had it 
in place in the stack, then tried changing to the heap to see if 
that would fix the problem. That didn’t work. I first ran the 
struct initialisation routine in each one of the unittests, but I 
still suspect that the thing is not completely initialised. Maybe 
I forgot to set something in the init routine and it gets set to 
a sensible value in subsequent code, but all that code is not 
running in the unittests. An uninitialised field would be my best 
guess. I can see the AAarch64 instruction that it dies on and my 
AAarch64 is non-existent but I’ve done so much asm over the years 
that I can hazard a guess. It is doing something like p->field 
and it looks like a read instruction but I’m not sure about the 
operand ordering as we probably have the stupid ATT asm to deal 
with. Of course a write instruction is more likely to cause a 
crash. I could try and work out how to see all the relevant 
registers, could be p is a null pointer or perhaps just out of 
range.


Really annoying as that code seems to work perfectly in normal 
use, and disabling that unittest block restores sanity. I really 
am going to have to go off and do a lot of reading.


Anyone help me with a stack dump?

2023-07-31 Thread Cecil Ward via Digitalmars-d-learn
The unitttests that I have just put in crash spectacularly with 
an access violation. I built the code with LDC for Aarch64 / OSX 
and I fired up lldb. I now have to learn lldb quick. (BTW Where 
can I get an x86 / linux build of lldb or similar ?)


This is the stack dump, and I could do with some help decoding 
parts of it


⋊> cecil@janet-mac-mini ⋊> ~/a/src clear; ./got   
  
  14:01:26
0   asm_parse   0x000102a157e4 
_D4core7runtime18runModuleUnitTestsUZ19unittestSegvHandlerUNbiPSQCk3sys5posix6signal9siginfo_tPvZv + 56
1   libsystem_platform.dylib0x0001a06f2a24 
_sigtramp + 56
2   asm_parse   0x00010297ed88 
_D4core8internal5array9appending__T15_d_arrayappendTHTAuTuZQyFNaNbNcNeMNkKQuMQxZQBa + 56

./got: line 7: 18387 Bus error: 10   ./asm_parse
⋊> cecil@janet-mac-mini ⋊> ~/a/src sudo lldb asm_parse
  
  14:02:49

Password:
(lldb) target create "asm_parse"
Current executable set to '/Users/cecil/asm_parse/src/asm_parse' 
(arm64).

(lldb) run
Process 18406 launched: '/Users/cecil/asm_parse/src/asm_parse' 
(arm64)

Process 18406 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = 
EXC_BAD_ACCESS (code=1, address=0xfff6)
frame #0: 0x0001a06f2860 
libsystem_platform.dylib`_platform_memmove + 544

libsystem_platform.dylib`:
->  0x1a06f2860 <+544>: ldpq0, q1, [x1, #-0x20]
0x1a06f2864 <+548>: subx1, x1, #0x20
0x1a06f2868 <+552>: subs   x2, x2, #0x20
0x1a06f286c <+556>: b.hi   0x1a06f2858   ; <+536>
Target 0: (asm_parse) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = 
EXC_BAD_ACCESS (code=1, address=0xfff6)
  * frame #0: 0x0001a06f2860 
libsystem_platform.dylib`_platform_memmove + 544
frame #1: 0x00016d88 
asm_parse`_D4core8internal5array9appending__T15_d_arrayappendTHTAuTuZQyFNaNbNcNeMNkKQuMQxZQBa + 56
frame #2: 0x0001b1fc 
asm_parse`_D9asm_parse__T20AsmTransformTemplateTuZ21__unittest_L1541_C1_1FZv + 628
frame #3: 0x00010006b9b8 asm_parse`asm_parse.__unittest + 
36
frame #4: 0x00010009d83c 
asm_parse`_D4core7runtime18runModuleUnitTestsUZ14__foreachbody6MFPS6object10ModuleInfoZi + 56
frame #5: 0x0001000ac620 
asm_parse`_D2rt5minfo17moduleinfos_applyFMDFyPS6object10ModuleInfoZiZ14__foreachbody2MFKSQCz19sections_elf_shared3DSOZi + 68
frame #6: 0x0001000acee0 
asm_parse`_D2rt19sections_elf_shared3DSO7opApplyFMDFKSQBqQBqQyZiZi + 56
frame #7: 0x0001000ac5b0 
asm_parse`_D2rt5minfo17moduleinfos_applyFMDFyPS6object10ModuleInfoZiZi + 32
frame #8: 0x0001000a21a4 
asm_parse`_D6object10ModuleInfo7opApplyFMDFPSQBhQBdZiZi + 32
frame #9: 0x00010009d6b0 asm_parse`runModuleUnitTests + 
184
frame #10: 0x0001000a6518 
asm_parse`_D2rt6dmain212_d_run_main2UAAamPUQgZiZ6runAllMFZv + 32

frame #11: 0x0001000a641c asm_parse`_d_run_main2 + 376
frame #12: 0x0001000a6288 asm_parse`_d_run_main + 148
frame #13: 0x0001a036bf28 dyld`start + 2236
(lldb)


Re: Unicode in strings

2023-07-27 Thread Cecil Ward via Digitalmars-d-learn

On Thursday, 27 July 2023 at 22:35:00 UTC, Adam D Ruppe wrote:

On Thursday, 27 July 2023 at 22:15:47 UTC, Cecil Ward wrote:
How do I get a wstring or dstring with a code point of 0xA0 in 
it ?


note that you don't need wstring and dstring to express all 
unicode strings.


I realised that I was probably generating UTF8 and only one byte, 
so I switched to \u00A0, I think. Must have got that wrong too 
because I was still getting the error message. I’ll try it again 
carefully.


Re: What is a dchar ?

2023-07-27 Thread Cecil Ward via Digitalmars-d-learn
On Wednesday, 26 July 2023 at 01:56:28 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
The spec says they are unsigned, so if ldc is using sign 
extension, that is probably a bug.


My fault, I reread the code and the sign-extension applies to 
something else, coincidentally right where I was looking at this. 
It uses signed 32-bit displacements in a case/switch table of 
offsets into the code segment, and that was what mislead me. It 
could have used unsigned displacements but then all the labels in 
the code would have to be above the reference base point, and 
this allows +/- offsets to anywhere. So my apologies.


Re: Giant template - changing types everywhere

2023-07-14 Thread Cecil Ward via Digitalmars-d-learn
On Friday, 14 July 2023 at 14:15:29 UTC, Steven Schveighoffer 
wrote:

On 7/14/23 1:51 AM, Cecil Ward wrote:

[...]


So templates don't automatically instantiate, you have to 
specify them. And then if your function is inside the template, 
to access it, you will need to do:


[...]


I can give you the code if you wish. I am cecil (at) cecil ward 
(dot) com. I can’t thank you enough for your generous help. I 
don’t want you to get sucked into a black hole with this though.


I don’t understand why the public keyword fails to work inside a 
template, but I suppose that that’s just a wishlist feature.


Re: Giant template - changing types everywhere

2023-07-13 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 14 July 2023 at 05:09:58 UTC, Cecil Ward wrote:

On Friday, 14 July 2023 at 05:05:27 UTC, Cecil Ward wrote:

On Friday, 14 July 2023 at 05:03:31 UTC, Cecil Ward wrote:
On Friday, 14 July 2023 at 01:34:54 UTC, Steven Schveighoffer 
wrote:

[...]


The way I can see it going is a giant template encompassing 
pretty much the whole file. Does that mean that the caller 
who calls my one public function does so by passing the type 
dchar or wchar ? And then we generate the strings from that. 
It might be rather more natural for the caller to pass one of 
the string types into the template. That’s where I get rather 
more confused, say caller calls


Transform(dstring)(dstring str)

or can they just do Transform( "str"d ) and it would work out 
that the type is immutable dchar[] ?


Perhaps I should just make up a small example file with two 
functions in it to see if I can get the syntax right?


If I wrap the whole thing with a template declaration of the 
xchar type, then can I get away with no changes to the 
individual function definitions?


I tried it, wrapped the whole thing in a template definition and 
it compiled, but then my test file which calls Transform( 
someDString ) failed to compile with errors saying it couldn’t 
find the definition of Transform in the other module, which is or 
was public. It’s as if it is no longer public because it’s now 
inside the template.


Re: Giant template - changing types everywhere

2023-07-13 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 14 July 2023 at 05:05:27 UTC, Cecil Ward wrote:

On Friday, 14 July 2023 at 05:03:31 UTC, Cecil Ward wrote:
On Friday, 14 July 2023 at 01:34:54 UTC, Steven Schveighoffer 
wrote:

[...]


The way I can see it going is a giant template encompassing 
pretty much the whole file. Does that mean that the caller who 
calls my one public function does so by passing the type dchar 
or wchar ? And then we generate the strings from that. It 
might be rather more natural for the caller to pass one of the 
string types into the template. That’s where I get rather more 
confused, say caller calls


Transform(dstring)(dstring str)

or can they just do Transform( "str"d ) and it would work out 
that the type is immutable dchar[] ?


Perhaps I should just make up a small example file with two 
functions in it to see if I can get the syntax right?


If I wrap the whole thing with a template declaration of the 
xchar type, then can I get away with no changes to the individual 
function definitions?


Re: Giant template - changing types everywhere

2023-07-13 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 14 July 2023 at 05:03:31 UTC, Cecil Ward wrote:
On Friday, 14 July 2023 at 01:34:54 UTC, Steven Schveighoffer 
wrote:

[...]


The way I can see it going is a giant template encompassing 
pretty much the whole file. Does that mean that the caller who 
calls my one public function does so by passing the type dchar 
or wchar ? And then we generate the strings from that. It might 
be rather more natural for the caller to pass one of the string 
types into the template. That’s where I get rather more 
confused, say caller calls


Transform(dstring)(dstring str)

or can they just do Transform( "str"d ) and it would work out 
that the type is immutable dchar[] ?


Perhaps I should just make up a small example file with two 
functions in it to see if I can get the syntax right?


Re: Giant template - changing types everywhere

2023-07-13 Thread Cecil Ward via Digitalmars-d-learn
On Friday, 14 July 2023 at 01:34:54 UTC, Steven Schveighoffer 
wrote:

On 7/13/23 8:08 PM, Cecil Ward wrote:

What I really want to do though is provide one single 
templated function with the kind of characters / strings as a 
parameter. I want to have something like

T Transform( T )( T str)
called as
auto result = Transform!(dstring)( dstring str );


```d
T[] Transform(T)(T[] str)
```

Note that you don't have to specify the type when calling:

```d
Transform(someDstring); // infers dchar
```

I’m quite confused as to how to proceed. This is quite a large 
module ~ 2k loc, and I don’t really want to go through and 
change every private function into a templated one. Should I 
just make the whole thing into a giant template containing 
many functions?


If you have more questions, please ask. Some examples of how 
making a template would be painful would be helpful.


-Steve


The way I can see it going is a giant template encompassing 
pretty much the whole file. Does that mean that the caller who 
calls my one public function does so by passing the type dchar or 
wchar ? And then we generate the strings from that. It might be 
rather more natural for the caller to pass one of the string 
types into the template. That’s where I get rather more confused, 
say caller calls


Transform(dstring)(dstring str)

or can they just do Transform( "str"d ) and it would work out 
that the type is immutable dchar[] ?


Giant template - changing types everywhere

2023-07-13 Thread Cecil Ward via Digitalmars-d-learn

Some advice on a couple of points.

I have been working on a module that works on either dchar / 
dstrings or wchar / wstrings with just two changes of alias 
definitions and a recompile.


What I really want to do though is provide one single templated 
function with the kind of characters / strings as a parameter. I 
want to have something like

T Transform( T )( T str)
called as
auto result = Transform!(dstring)( dstring str );

I only want to have one type as a parameter and derive other 
types from that: xstrings from xchars and I’ll need types of 
xchar arrays that are mutable and immutable.


I’m quite confused as to how to proceed. This is quite a large 
module ~ 2k loc, and I don’t really want to go through and change 
every private function into a templated one. Should I just make 
the whole thing into a giant template containing many functions?


Re: Installing GDC / Linux / x86-64 when apt-get doesn’t work

2023-07-11 Thread Cecil Ward via Digitalmars-d-learn

On Tuesday, 11 July 2023 at 05:49:36 UTC, Sergey wrote:

On Tuesday, 11 July 2023 at 04:11:38 UTC, Cecil Ward wrote:
I’m trying to install GDC on a new Linux box and I don’t know 
what I’m doing. Background: I have installed LDC successfully 
and have installed GDC on a Raspberry Pi using 32-bit ARM.


For some reason the apt-get command doesn’t work on this 
machine, don’t know why. The machine is a virtual server 
hosted on the internet and I can get support for the o/s.


What is the recommended procedure for fetching the x86-64 
prec-compiled GDC?


Check the web about reprex and write what have you tried to 
run, which error you got, some more information about the 
system, root rights.


Have you tried to download deb package manually and use dpkg 
command?


I think the problem might have been that I did apt-get not apt 
and I was not running as root, just now I elevated with sudo and 
ran apt -y install gdc and that worked so by fumbling about I 
appear to have solved it.


That was the x86-64 box. I haven’t been able to install GDC on my 
Apple M2 ARM Aarch64 Mac though, no idea how to find it for OSX 
Aarch64.


Re: Installing GDC / Linux / x86-64 when apt-get doesn’t work

2023-07-10 Thread Cecil Ward via Digitalmars-d-learn

On Tuesday, 11 July 2023 at 04:11:38 UTC, Cecil Ward wrote:
I’m trying to install GDC on a new Linux box and I don’t know 
what I’m doing. Background: I have installed LDC successfully 
and have installed GDC on a Raspberry Pi using 32-bit ARM.


For some reason the apt-get command doesn’t work on this 
machine, don’t know why. The machine is a virtual server hosted 
on the internet and I can get support for the o/s.


What is the recommended procedure for fetching the x86-64 
prec-compiled GDC?


The OS is Debian v 12 x86_64.


Installing GDC / Linux / x86-64 when apt-get doesn’t work

2023-07-10 Thread Cecil Ward via Digitalmars-d-learn
I’m trying to install GDC on a new Linux box and I don’t know 
what I’m doing. Background: I have installed LDC successfully and 
have installed GDC on a Raspberry Pi using 32-bit ARM.


For some reason the apt-get command doesn’t work on this machine, 
don’t know why. The machine is a virtual server hosted on the 
internet and I can get support for the o/s.


What is the recommended procedure for fetching the x86-64 
prec-compiled GDC?


Pre-expanding alloc cell(s) / reserving space for an associative array

2023-07-09 Thread Cecil Ward via Digitalmars-d-learn
Before I posted a question about avoiding unnecessary 
allocs/reallocs when adding entries to an array like so

uint[ dstring ]  arr;

when I build it up from nothing with successive insertions.

The array is accessed by a key that is a dstring. I was told that 
I can’t use .reserve or the like on it? Is that correct? My 
memory fails me, powerful pain drugs.


Is there an alternate method I could use ? To be honest, the 
number of entries is likely to be extremely modest, so this is 
not a huge performance issue, six entries would be considered 
quite a lot. The string keys are probably not very very long. But 
I’m learning good habits for the day when I might have a bigger 
such database.


Re: Inlined functions and their original bodies - bloat

2023-07-09 Thread Cecil Ward via Digitalmars-d-learn

On Sunday, 9 July 2023 at 18:04:13 UTC, Cecil Ward wrote:
I have a program where the various routines are all marked 
pragma( inline, true ). The compiler obeys this but the LDC and 
GDC compilers still compile the function bodies even though the 
bodies are not needed as they are supposed to be ‘private’ to 
the module, explicitly marked as such, hoping that that is like 
static in C. There are no pointers to the routines, so no need 
for the bodies because of any indirect calls. Is there a way to 
control this code bloat in LDC / GDC ? Using the godbolt 
compiler explorer with LDC and GDC I can indeed see that the 
code is being inlined. Does this count as a compiler 
performance-type bug?


This is with full -O3 optimisation and -release / -frelease for 
LDC and GDC respectively.


Re: Toolchain with ldc and AArch64 OSX

2023-07-09 Thread Cecil Ward via Digitalmars-d-learn

On Sunday, 9 July 2023 at 05:32:56 UTC, Danilo Krahn wrote:

On Saturday, 24 June 2023 at 15:16:37 UTC, Cecil Ward wrote:
I have LDC running on an ARM Mac. If anyone else out there is 
an LDC or GDC user, could you knock up a quick shell program 
to compile and link a .d file to produce an executable ? found 
the linker but these tools are all new to me and a bit of help 
would save me a lot of trial and error and frustration as I 
try to find docs. GDC would be great too.


I have managed to achieve this before on a Raspberry Pi 
AArch64 Linux Debian where the compiler can link and generate 
an executable just in integrated fashion in the one command. 
The OSX tools seem rather different however.


```d
import std.stdio : writeln;

void main() {
writeln("Hello, world!");
}
```

Compilation using LDC on macOS is just:

```
ldc2 --release --O3 main.d
```

Or some more options, to reduce executable size:

```
ldc2 --release --O3 --flto=full -fvisibility=hidden 
-defaultlib=phobos2-ldc-lto,druntime-ldc-lto -L=-dead_strip 
-L=-x -L=-S -L=-lz main.d

```

Executable size using first command: 1.3MB
Executable size using second command: 756KB


Brilliant, much appreciated! :) I posted ages ago about the bloat 
that I see where function bodies are compiled even though they 
are in fact always inlined and so the original body is never 
needed. The address of these functions is not taken, so no 
indirect pointer calling, and the functions are all explicitly 
private which I hope is like static in C? Anyway, no one is 
calling them from outside the module.


Re: Dynamic array of strings and appending a zero length array

2023-07-09 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 8 July 2023 at 20:01:08 UTC, H. S. Teoh wrote:
On Sat, Jul 08, 2023 at 05:15:26PM +, Cecil Ward via 
Digitalmars-d-learn wrote:
I have a dynamic array of dstrings and I’m spending dstrings 
to it. At one point I need to append a zero-length string just 
to increase the length of the array by one but I can’t have a 
slot containing garbage. I thought about ++arr.length - would 
that work, while giving me valid contents to the final slot ?


Unlike C/C++, the D runtime always ensures that things are 
initialized unless you explicitly tell it not to (via 
void-initialization). So ++arr.length will work; the new 
element will be initialized to dstring.init (which is the empty 
string).



T


Many thanks, it might give me a slightly better result just doing 
++arr.length;


Re: Dynamic array of strings and appending a zero length array

2023-07-08 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 8 July 2023 at 17:15:26 UTC, Cecil Ward wrote:
I have a dynamic array of dstrings and I’m spending dstrings to 
it. At one point I need to append a zero-length string just to 
increase the length of the array by one but I can’t have a slot 
containing garbage. I thought about ++arr.length - would that 
work, while giving me valid contents to the final slot ?


[...]


s/spending/appending/


Dynamic array of strings and appending a zero length array

2023-07-08 Thread Cecil Ward via Digitalmars-d-learn
I have a dynamic array of dstrings and I’m spending dstrings to 
it. At one point I need to append a zero-length string just to 
increase the length of the array by one but I can’t have a slot 
containing garbage. I thought about ++arr.length - would that 
work, while giving me valid contents to the final slot ?


What I first did was
   arr ~= [];

This gave no errors but it doesn’t increase the array length, so 
it seems. Is that a bug ? Or is it supposed to do that?


Then I tried
arr ~= ""d;
and that did work. Is there anything more efficient that I could 
do instead?


I actually have an alias for the type of the strings so that they 
can be either dstrings or wstrings with just a recompilation. How 
should I then generate a zero-length string that has th correct 
type of dstring or wstring as I am stuck with the ‘d’-suffix on 
the end of the ""d at the moment. Can I just cast ? Not a 
reinterpret cast, but a proper value conversion?


Re: Public visible entities published by a module

2023-07-07 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 7 July 2023 at 19:49:06 UTC, Anonymouse wrote:

On Friday, 7 July 2023 at 17:46:09 UTC, Cecil Ward wrote:

[...]


I did this. It's super ugly and even has `__traits(compiles)` 
in there, but as a quick and dirty solution it served well 
enough.


```d
void printPublicMembersOfModule(string module_)()
{
mixin("import thisModule = " ~ module_ ~ ";");

foreach (symstring; __traits(allMembers, thisModule))
{
alias symbol = __traits(getMember, thisModule, 
symstring);

static if (
__traits(compiles, __traits(getVisibility, symbol)) 
&&

__traits(getVisibility, symbol) == "public")
{
pragma(msg, symstring);
}
}
}

void main()
{
printPublicMembersOfModule!"std.stdio"();
}
```

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


Wow, thankyou so much for your generous reply.


Public visible entities published by a module

2023-07-07 Thread Cecil Ward via Digitalmars-d-learn
A bit of a weird question, and I’m not sure how to word it. Say I 
have a module, and I’d like to list / enumerate all the public 
visible things that the module exports / publishes ‘ makes 
visible. Is there a way of doing that ? Of getting that kind of 
listing?


I’m wondering about information leaking when things should be 
encapsulated.


Re: First module

2023-07-07 Thread Cecil Ward via Digitalmars-d-learn
On Friday, 7 July 2023 at 14:18:35 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

1. Compiler reads in source code provided on cli
2. It gets parsed
3. imports get looked up, if not already read in, looks in the 
directories provided by -I based upon the full module + package 
import statement

4. Finish compilation
5. Linker gets passed object files to produce some artifact 
like an executable


Very rough idea of how it works, but will do for what you are 
asking about.


As long as you compile all at once, assume inlining will work 
if it thinks it should. Modules will not affect it.


Brilliant, thanks Rikki.


Re: First module

2023-07-07 Thread Cecil Ward via Digitalmars-d-learn

On Thursday, 6 July 2023 at 21:10:39 UTC, Cecil Ward wrote:
I’ve written my first non-trivial module in D. See other 
thread. 
https://forum.dlang.org/thread/pfjpqcywxrmxwsncy...@forum.dlang.org


I’d like to set up something to call it from other modules, and 
specifically I’d like to see if inlining works across module 
boundaries - I have no idea whether it does or not as I don’t 
understand fully in detail how module imports work.


How do I go about setting up such a test harness with LDC (or 
GDC) on either OSX/ARM or Linux Debian x86-64? I’m not sure 
what tools I need.


Note that I cannot use DMD, this code is LDC/GDC-specific. LDC 
would be my preference as that is what it is ultimately aimed 
at.


Do I just provide two filenames as inputs to the compiler ? I’m 
wondering if the compiler resolves the import statements rather 
than the linker - is that right? I only have a vague 
understanding of how the import statement works - pulling in 
digested intermediate-code or something?


Will in-line functions be inlined even if the called routine is 
across a module boundary?


Re: Advice on debugging possible exception or crash

2023-07-06 Thread Cecil Ward via Digitalmars-d-learn

On Thursday, 6 July 2023 at 19:53:39 UTC, Chris Katko wrote:

On Thursday, 6 July 2023 at 06:00:04 UTC, Cecil Ward wrote:
My program is instrumented with a load of writeflns. At one 
point it looks as though it suddenly quits prematurely because 
the expected writeflns are not seen in the output. It could be 
that I am just reading the flow of control wrong as it goes 
ret, ret etc. I’m wondering if it is throwing an exception, or 
has a fault initiating a crash, perhaps even due to the 
fetching of arguments of one of the writeflns. In my limited 
experience, exceptions produce an error message though, and 
I’m not seeing anything. Any advice on how to debug this, 
silent termination ?


I don’t have a debugger on this machine, but on an x86-64 box 
I could use gdb if I first take the time to work out how.


one thing I do is have gdb/lldb break on d assert, before it 
destroys the stack. That helped me catch a class of bugs.


```sh
# in the gdb interface before running
break _d_assertp
break _d_assert
break _d_assert_msg

# or to combine it into the commandline:
gdb -ex "break _d_assert" -ex "break _d_assert_msg" -ex "run 
$1" ./main


# can also add it to your .gdbinit startup code.



This is brilliant advice. I’m building with LDC and in debug mode 
with -g, however gdb says it can’t find any symbol table or debug 
info, can’t even set breakpoints by line numbers. The Matt 
Godbolt Compiler Explorer can go to source line numbers in the 
asm. So I’m just missing something.




First module

2023-07-06 Thread Cecil Ward via Digitalmars-d-learn
I’ve written my first non-trivial module in D. See other thread. 
https://forum.dlang.org/thread/pfjpqcywxrmxwsncy...@forum.dlang.org


I’d like to set up something to call it from other modules, and 
specifically I’d like to see if inlining works across module 
boundaries - I have no idea whether it does or not as I don’t 
understand fully in detail how module imports work.


How do I go about setting up such a test harness with LDC (or 
GDC) on either OSX/ARM or Linux Debian x86-64? I’m not sure what 
tools I need.


Note that I cannot use DMD, this code is LDC/GDC-specific. LDC 
would be my preference as that is what it is ultimately aimed at.


Re: Advice on debugging possible exception or crash

2023-07-06 Thread Cecil Ward via Digitalmars-d-learn
On Thursday, 6 July 2023 at 07:09:11 UTC, Richard (Rikki) Andrew 
Cattermole wrote:


On 06/07/2023 7:07 PM, Cecil Ward wrote:
On Thursday, 6 July 2023 at 06:17:34 UTC, Richard (Rikki) 
Andrew Cattermole wrote:

2 Recommendations:

1. Attach a debugger
2. Make sure to flush stdout whenever you write


I assumed that buffering was to blame. How do I flush stdout?


stdout.flush;

https://dlang.org/phobos/std_stdio.html#.stdout


Many, many thanks once again.


Re: Advice on debugging possible exception or crash

2023-07-06 Thread Cecil Ward via Digitalmars-d-learn
On Thursday, 6 July 2023 at 06:17:34 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

2 Recommendations:

1. Attach a debugger
2. Make sure to flush stdout whenever you write


I assumed that buffering was to blame. How do I flush stdout?

I moved to an x86-64 box. I was using my ARM M2 Mac for which I 
have no debugger. There must be one somewhere though. I got a 
visible crash on the x86 machine, array index off the end by one, 
so I attached gdb and saw the bug. Yay!


I’m not sure why there was no crash error message on the ARM Mac 
though. I had the array length wildly wrong. I then fixed the 
offending code that was doing the accounting wrongly.


Advice on debugging possible exception or crash

2023-07-06 Thread Cecil Ward via Digitalmars-d-learn
My program is instrumented with a load of writeflns. At one point 
it looks as though it suddenly quits prematurely because the 
expected writeflns are not seen in the output. It could be that I 
am just reading the flow of control wrong as it goes ret, ret 
etc. I’m wondering if it is throwing an exception, or has a fault 
initiating a crash, perhaps even due to the fetching of arguments 
of one of the writeflns. In my limited experience, exceptions 
produce an error message though, and I’m not seeing anything. Any 
advice on how to debug this, silent termination ?


I don’t have a debugger on this machine, but on an x86-64 box I 
could use gdb if I first take the time to work out how.


Re: Zapping a dynamic string

2023-07-04 Thread Cecil Ward via Digitalmars-d-learn
On Tuesday, 4 July 2023 at 17:46:22 UTC, Steven Schveighoffer 
wrote:

On 7/4/23 1:01 PM, Cecil Ward wrote:
I have a mutable dynamic array of dchar, grown by successively 
appending more and more. When I wish to zap it and hand the 
contents to the GC to be cleaned up, what should I do? What 
happens if I set the .length to zero?


If you want to forget it so the GC can clean it up, set it to 
`null`. If you set the length to 0, the array reference is 
still pointing at it.


If you want to reuse it (and are sure that no other things are 
referring to it), you can do:


```d
arr.length = 0;
arr.assumeSafeAppend;
```

Now, appending to the array will reuse the already-allocated 
buffer space. Obviously, if you have data in there that is 
still used, you don't want to use this option.


-Steve


Many many thanks for that tip, Steve!


Inserting into zero-length dynamic array

2023-07-04 Thread Cecil Ward via Digitalmars-d-learn
I have a dynamic array of strings of length zero. When i write to 
the first element the program crashes, not surprisingly, but what 
should I be doing?


 dstring[] arr;

 arr[0] = "my string"d; // BANG !!


Re: Zapping a dynamic string

2023-07-04 Thread Cecil Ward via Digitalmars-d-learn

On Tuesday, 4 July 2023 at 17:01:42 UTC, Cecil Ward wrote:
I have a mutable dynamic array of dchar, grown by successively 
appending more and more. When I wish to zap it and hand the 
contents to the GC to be cleaned up, what should I do? What 
happens if I set the .length to zero?


I do want to restart the .length at zero in any case as I’m going 
to begin the appending afresh, so I wish to restart from nothing.


Re: Bug in usage of associative array: dynamic array with string as a key

2023-06-30 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 30 June 2023 at 19:05:23 UTC, Cecil Ward wrote:

I have code roughly like the following:

   dstring str = "name"d;
   uint ordinal =  (( str in Decls.ordinals ) !is null)  ?  
Decls.ordinals[ str ]  :  -1;


struct Decls
   {
   uint[ dstring]   ordinals;
   }

//and
   Decls.ordinals[ str ] = ordinal_counter++;

The problem is that it always returns ordinal== -1 from the 
expression. Can you sort me out? I took this from the example 
given in the language reference under arrays, testing for 
membership (or similar, I forget the subssection title).


From good old printfs it seems to be the case that the array is 
being populated (elsewhere) with the expected correct values. 
Taking out the if doesn’t seem to help either. I don’t have a 
way of examining the contents of the dynamic array directly to 
check that they are actually being stored as expected, other 
than seeing that that line of code is indeed being executed 
with the expected values of str going in. Note that I’m using 
32-bit dstrings everywhere, not strings of bytes.


Fool that I am. I did those good old printfs a while back, and 
now I recheck them I see that something has become broken and it 
seems that the insertions are not happening now. So thankyou for 
your kindness and I’ll post again if that doesn’t solve the 
non-issue.


Re: Bug in usage of associative array: dynamic array with string as a key

2023-06-30 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 30 June 2023 at 21:25:23 UTC, H. S. Teoh wrote:
On Fri, Jun 30, 2023 at 07:05:23PM +, Cecil Ward via 
Digitalmars-d-learn wrote: [...]


It would help if you could post the complete code that 
reproduces the problem. Or, if you do not wish to reveal your 
code, reduce it to a minimal case that still exhibits the same 
problem, so that we can see it for ourselves.  The snippets you 
provided do not provide enough information to identify the 
problem.



T


I would indeed need to cut it down massively, as the original 
code is ~2k lines. Mind you, I will just end up with the example 
at https://dlang.org/spec/hash-map.html#testing_membership in the 
language docs, under associative arrays - 13.3 testing 
membership. Would anyone else care to try that example out as 
that might be quicker? That’s because as all I did was copy that 
basically, with the only substantive change being deleting the 
variable p, but I’m still testing whether or not I get a null 
pointer.


I thought I had checked that the insertions were all as expected, 
so I’ll go and recheck that next.


Re: Bug in usage of associative array: dynamic array with string as a key

2023-06-30 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 30 June 2023 at 19:58:39 UTC, FeepingCreature wrote:

On Friday, 30 June 2023 at 19:05:23 UTC, Cecil Ward wrote:

I have code roughly like the following:

   dstring str = "name"d;
   uint ordinal =  (( str in Decls.ordinals ) !is null)  ?  
Decls.ordinals[ str ]  :  -1;


struct Decls
   {
   uint[ dstring]   ordinals;
   }

//and
   Decls.ordinals[ str ] = ordinal_counter++;

The problem is that it always returns ordinal== -1 from the 
expression. Can you sort me out?


Impossible to tell without a complete repro, I'm afraid. The 
expression, at least, looks correct at first glance.


Note that you can do `uint ordinal = Decls.ordinals.get(str, 
-1);`.


Is the second argument an ‘else’ then, my friend?


Re: Bug in usage of associative array: dynamic array with string as a key

2023-06-30 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 30 June 2023 at 20:12:08 UTC, Ali Çehreli wrote:

On 6/30/23 12:05, Cecil Ward wrote:
> I have code roughly like the following:
>
> dstring str = "name"d;

Aside: One almost never needs dstring.

> uint ordinal =  (( str in Decls.ordinals ) !is null)  ?
> Decls.ordinals[ str ]  :  -1;
>
> struct Decls
> {
> uint[ dstring]   ordinals;

Do you mean 'ordinals' is 'static'? Otherwise, Decls.ordinals 
does not compile.


> }
>
> //and
> Decls.ordinals[ str ] = ordinal_counter++;

Are you doing that *after* you initialize 'ordinal' as you show 
here? :)


Ali


Hi Ali, ‘ordinal’ is a static initialised explicitly with zero.


Bug in usage of associative array: dynamic array with string as a key

2023-06-30 Thread Cecil Ward via Digitalmars-d-learn

I have code roughly like the following:

   dstring str = "name"d;
   uint ordinal =  (( str in Decls.ordinals ) !is null)  ?  
Decls.ordinals[ str ]  :  -1;


struct Decls
   {
   uint[ dstring]   ordinals;
   }

//and
   Decls.ordinals[ str ] = ordinal_counter++;

The problem is that it always returns ordinal== -1 from the 
expression. Can you sort me out? I took this from the example 
given in the language reference under arrays, testing for 
membership (or similar, I forget the subssection title).


From good old printfs it seems to be the case that the array is 
being populated (elsewhere) with the expected correct values. 
Taking out the if doesn’t seem to help either. I don’t have a way 
of examining the contents of the dynamic array directly to check 
that they are actually being stored as expected, other than 
seeing that that line of code is indeed being executed with the 
expected values of str going in. Note that I’m using 32-bit 
dstrings everywhere, not strings of bytes.




Re: Debugging by old fashioned trace log printfs / writefln

2023-06-30 Thread Cecil Ward via Digitalmars-d-learn

On Thursday, 29 June 2023 at 23:54:45 UTC, Chris Katko wrote:

On Thursday, 29 June 2023 at 18:27:22 UTC, Cecil Ward wrote:
I’m trying to debug my D program with old-fashioned printfs 
stuck in various strategic places, actually using writefln(). 
My problem is that the addition of printf fights with the 
existing declarations for pure nothrow @nogc @safe and I have 
to adjust them, then put them back correctly when the 
writefln() trace statements are later removed.


Is there something else I could be using, something that is 
allowed to violate the checking rules for purity, nothrow, 
@nogc? Would pragma( msg, "…" ) do the trick? Is that what I 
should be using?


pragma(msg, "") is only for compile time. It for debugging 
functions/templates if they're actually used (which static path 
is used), instantiated, and you can also get type values from 
template inputs to confirm they're what you expect. "Oh this is 
a char[][] not a char[]!"


pragmas are the D equivalent of C/C++ pragmas. In this case, 
C/C++:

```C
#pragma message( message-string )
```


Since I can pass my main function some compile-time-defined 
input, the whole program should be capable of being executed with 
CTFE, no? So in that case pragma( msg ) should suffice for a test 
situation? Would pragma(message) have the advantage over writefln 
that I don’t have to pervert the function attributes like nogc 
nothrow pure ?


Debugging by old fashioned trace log printfs / writefln

2023-06-29 Thread Cecil Ward via Digitalmars-d-learn
I’m trying to debug my D program with old-fashioned printfs stuck 
in various strategic places, actually using writefln(). My 
problem is that the addition of printf fights with the existing 
declarations for pure nothrow @nogc @safe and I have to adjust 
them, then put them back correctly when the writefln() trace 
statements are later removed.


Is there something else I could be using, something that is 
allowed to violate the checking rules for purity, nothrow, @nogc? 
Would pragma( msg, "…" ) do the trick? Is that what I should be 
using?


Re: Counting an initialised array, and segments

2023-06-26 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 26 June 2023 at 22:19:25 UTC, Jonathan M Davis wrote:
On Monday, June 26, 2023 1:09:24 PM MDT Cecil Ward via 
Digitalmars-d-learn wrote:

[...]


[...]


I completely agree with everything you said. I merely used 
aliases to give me the freedom to switch between having text in 
either UTF16 or UTF32 in memory, and see how the performance 
changes. That’s the only reason for me doing that. I also want to 
keep a clear distinction between words in me memory and code 
points in registers.


Re: Counting an initialised array, and segments

2023-06-26 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 26 June 2023 at 12:28:15 UTC, Jonathan M Davis wrote:
On Monday, June 26, 2023 5:08:06 AM MDT Cecil Ward via 
Digitalmars-d-learn wrote:
On Monday, 26 June 2023 at 08:26:31 UTC, Jonathan M Davis 
wrote:

> On Sunday, June 25, 2023 4:08:19 PM MDT Cecil Ward via
>
> Digitalmars-d-learn wrote:
>> I recently had some problems
>>
>> dchar[] arr = [ ‘ ‘, TAB, CR, LF … ];
>>
>> and I got errors from the compiler which led to me having to
>> count the elements in the initialiser and declare the array
>> with
>> an explicit size. I don’t want the array to be mutable so I
>> later
>> added immutable to it, but that didn’t help matters. At one
>> point, because the array was quite long, I got the arr[
>> n_elements ] number wrong, it was too small and the 
>> remainder

>> of
>> the array was full of 0xffs (or something), which was good,
>> helped me spot the bug.
>>
>> Is there any way to get the compiler to count the number of 
>> elements in the initialiser and set the array to that size 
>> ? And it’s immutable.

>
> Without seeing the errors, I can't really say what the 
> problem was, but most character literals are going to be 
> char, not dchar, so you may have had issues related to the 
> type that the compiler was inferring for the array literal. 
> I don't recall at the moment how exactly the compiler 
> decides the type of an array literal when it's given values 
> of differing types for the elements.

>
> Either way, if you want a static array, and you don't want 
> to have to count the number of elements, then 
> https://dlang.org/phobos/std_array.html#staticArray should 
> take care of that problem.

>
> - Jonathan M Davis

Where I used symbolic names, such as TAB, that was defined as 
an

int (or uint)
enum TAB = 9;
or
enum uint TAB = 9;
I forget which. So I had at least one item that was typed
something wider than a char.

I tried the usual sizeof( arr )/ sizeof dchar, compiler 
wouldn’t
have that for some reason, and yes I know it should be D 
syntax,

god how I long for C sizeof()!


sizeof is a property in D. So, you can do char.sizeof or 
varName.sizeof. But regardless, there really is no reason to 
use sizeof with D arrays under normal circumstances. And in the 
case of dynamic arrays, sizeof will give you the size of the 
dynamic array itself, not the slice of memory that it refers 
to. You're essentially using sizeof on


struct DynamicArray(T)
{
size_t length;
T* ptr;
}

which is not going to tell you anything about the memory it 
points to. The length property of an array already tells you 
the length of the array (be it static or dynamic), so using 
sizeof like you're talking about really does not apply to D.


And I wouldn't advise using uint for a character in D. That's 
what char, wchar, and dchar are for. Depending on the 
circumstances, you get implicit conversions between character 
and integer types, but they are distinct types, and mixing and 
matching them willy-nilly could result in compilation errors 
depending on what your code is doing.


- Jonathan M Davis


No, point taken, a sloppy example. I don’t in fact do that in the 
real code. I use dchar everywhere appropriate instead of uint. In 
fact I have aliases for dstring and dchar and successfully did an 
alternative build with the aliases renamed to use 16-bits wchar / 
w string instead of 32-bits and rebuilt and all was well, just to 
test that it is code word size-independent. I would need to do 
something different though if I ever decided to change to use 
16-bit code words in memory because I would still be wanting to 
manipulate 32-bit values for char code points when they are being 
handled in registers, for efficiency too as well as code 
correctness, as 16-bit ‘partial words’ are bad news for 
performance on x86-64. I perhaps ought to introduce a new alias 
called codepoint, which is always 32-bits, to distinguish dchar 
in registers from words in memory. It turns out that I can get 
away with not caring about utf16, as I’m merely _scanning_ a 
string. I couldn’t ever get away with changing the in-memory code 
word type to be 8-bit chars, and then using utf8 though, as I do 
occasionally deal with non-ASCII characters, and I would have to 
either preconvert the Utf8 to do the decoding, or parse 8-bit 
code words and handle the decoding myself on the fly which would 
be madness. If I have to handle utf8 data I will just preconvert 
it.


Re: Scope guards

2023-06-26 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 26 June 2023 at 17:41:16 UTC, Paul Backus wrote:

On Saturday, 24 June 2023 at 17:00:36 UTC, Cecil Ward wrote:
I would like to use scope guards but in the guard I need to 
get access to some local variables at the end of the routine. 
This doesn’t really seem to make sense as to how it would 
work, because their values depend on the exact point where the 
scope guard is called at in the last, exiting line(s) of the 
routine. Am I misunderstanding?


Scope guards are syntax sugar for try/catch/finally. For 
example, when you write


auto f = open("foo");
scope(exit) close(f);
doSomethingWith(f);

...it gets transformed by the compiler into

auto f = open("foo");
try {
doSomethingWith(f);
} finally {
close(f);
}

I do not understand exactly what the problem is you are having, 
but hopefully this lets you figure out how to solve it.


Sorry for being stupid, but say you have something like this

==
{
size_t p = offset;
++p;
scope(exit) { writeOutput( 0, p );

++p
…
++p;

return;
}

==

The correctness of its behaviour depends on what the value of p 
is when it calls writeOutput(), and the value of p is being 
changed. To be correct, the final value of p needs to be passed 
to writeOutput( p ). That was what I was worrying about. I could 
have course introduce another variable to capture this final 
value and use that in the scope guard, but then I can’t make the 
scope guard general if I have more than one exit route. The 
compiler sounded as if it did not like the local variable p in 
the scope guard, but I need to try it again to get the error 
message.


Re: Counting an initialised array, and segments

2023-06-26 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 26 June 2023 at 08:26:31 UTC, Jonathan M Davis wrote:
On Sunday, June 25, 2023 4:08:19 PM MDT Cecil Ward via 
Digitalmars-d-learn wrote:

I recently had some problems

dchar[] arr = [ ‘ ‘, TAB, CR, LF … ];

and I got errors from the compiler which led to me having to
count the elements in the initialiser and declare the array 
with
an explicit size. I don’t want the array to be mutable so I 
later

added immutable to it, but that didn’t help matters. At one
point, because the array was quite long, I got the arr[
n_elements ] number wrong, it was too small and the remainder 
of

the array was full of 0xffs (or something), which was good,
helped me spot the bug.

Is there any way to get the compiler to count the number of 
elements in the initialiser and set the array to that size ? 
And it’s immutable.


Without seeing the errors, I can't really say what the problem 
was, but most character literals are going to be char, not 
dchar, so you may have had issues related to the type that the 
compiler was inferring for the array literal. I don't recall at 
the moment how exactly the compiler decides the type of an 
array literal when it's given values of differing types for the 
elements.


Either way, if you want a static array, and you don't want to 
have to count the number of elements, then 
https://dlang.org/phobos/std_array.html#staticArray should take 
care of that problem.


- Jonathan M Davis


Where I used symbolic names, such as TAB, that was defined as an 
int (or uint)

enum TAB = 9;
or
enum uint TAB = 9;
I forget which. So I had at least one item that was typed 
something wider than a char.


I tried the usual sizeof( arr )/ sizeof dchar, compiler wouldn’t 
have that for some reason, and yes I know it should be D syntax, 
god how I long for C sizeof()!


Counting an initialised array, and segments

2023-06-25 Thread Cecil Ward via Digitalmars-d-learn

I recently had some problems

dchar[] arr = [ ‘ ‘, TAB, CR, LF … ];

and I got errors from the compiler which led to me having to 
count the elements in the initialiser and declare the array with 
an explicit size. I don’t want the array to be mutable so I later 
added immutable to it, but that didn’t help matters. At one 
point, because the array was quite long, I got the arr[ 
n_elements ] number wrong, it was too small and the remainder of 
the array was full of 0xffs (or something), which was good, 
helped me spot the bug.


Is there any way to get the compiler to count the number of 
elements in the initialiser and set the array to that size ? And 
it’s immutable.


The only reason that I’m giving it a name is that I want the 
object to be used in several places and I don’t want multiple 
copies of it in the code/readonly initialised data segment.


Another couple of unrelated questions: is there such a thing as a 
no-execute initialised readonly data segment? I’m seeing 
immutables going into the code segment, I think, with x86 LDC at 
least, can’t remember about GDC. Anyway on x86-64 immutables are 
addressed as [rip + displ] which is very pleasing as it’s vastly 
more efficient than accessing statics in TLS which seems to be a 
nightmare in Linux at least.


In MS Windows, isn’t TLS dealt with using FS: ( or GS: ?) 
prefixes? Shame this doesn’t seem to be exploited in Linux, or am 
I wrong?


I’d like to deal with the overhead of retrieving the static base 
address all the time in the Linux situation (if I have got the 
right end of the stick) but having an ‘application object’ which 
contains all the statics in a struct in an alloc cell or 
something, and passing a pointer to this static base app object 
everywhere seems a nightmare too as it eats a register and worse 
eats one of the limited number of precious function argument 
registers which are in short supply in eg x86-64, where there are 
less than half a dozen argument registers allowed. I realise that 
one can deal with that limited number by rolling some passed 
arguments up into a passed struct, but that’s introducing a level 
of indirection and other overhead, that or just live with the 
fact that the extra args are going into the stack, which isn’t 
the worst thing in the world. I wonder what others do about 
statics in TLS?


Re: Large statics

2023-06-25 Thread Cecil Ward via Digitalmars-d-learn

On Sunday, 25 June 2023 at 21:08:13 UTC, Ali Çehreli wrote:

On 6/25/23 13:41, Cecil Ward wrote:

> The docs say that there is a limit on the size of large
statics

Customers (at least Weka) did request larger statics in the 
past. Since they use LDC, the limit was removed for LDC. I did 
not try it. :)


Ali


Ah, I did not know that, many thanks, I’m using LDC and GDC.

A wishlist for the docs on the website would be to have them 
mention, and link to additional documentation regarding GDC and 
LDC, not just DMD. The docs should mainly be about the D language 
not solely about the DMD compiler.


Large statics

2023-06-25 Thread Cecil Ward via Digitalmars-d-learn
The docs say that there is a limit on the size of large statics 
of 16 MB. Is it desirable to remove this limit ? I realise that 
with new code there is the option to alloc the space instead 
where the static is uninitialised. There are other possibilities, 
such as an object filled with compile-time generated data maybe. 
The documentation also points out the crazy but understandable 
bloat on the exe size.


Is it possible to place a large object in BSS by using
  ubyte arr[ enormous ] = void;


Re: Mixin and compile-time functions for code generation

2023-06-24 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 24 June 2023 at 17:43:52 UTC, Adam D Ruppe wrote:

On Saturday, 24 June 2023 at 17:31:31 UTC, Cecil Ward wrote:
Can I get mixin whatever to do this for me? Mixin with a 
function that runs at compile-time and creates the required 
source ?


have you tried it?


No, not so far. Adam, if you think that is a workable approach 
then I certainly will do so. It’s going to be very awkward 
generating literal strings in D code using literal strings in the 
meta-mixin-code or whatever I should call it.


Mixin and compile-time functions for code generation

2023-06-24 Thread Cecil Ward via Digitalmars-d-learn
I have a function that can be run at compile-time and which will 
be able to output code to be injected into the D source code 
stream. Can I get mixin whatever to do this for me? Mixin with a 
function that runs at compile-time and creates the required 
source ? Like D’s solution for a replacement for function-style C 
preprocessor macros ? - but far more advanced and capable ?


I need to re-read Ali Çehreli’s excellent book for the third time.


Re: How does D’s ‘import’ work?

2023-06-24 Thread Cecil Ward via Digitalmars-d-learn

On Tuesday, 20 June 2023 at 17:56:27 UTC, Ali Çehreli wrote:

On 6/20/23 08:09, Cecil Ward wrote:

> I’m used to slow compilers on fast machines and compiling
> gives me an excuse for more coffee and possibly fruity buns.

Yes, all of us in past projects accepted C++'s slowness. We did 
get coffee, etc. One of my current colleagues regularly plays 
solitaire when waiting for C++ compilations. Not only it's not 
a professional sight, but C++ is proving to be a professional 
mistake.


Nobody should suffer from such context switches. I have a 
hunch, without any backing research data, that C++'s 
contribution to humanity may be net negative.


D is nothing like that: My turnaround is a few seconds: Write, 
compile, run, see the effect... I use only dmd partly because 
of laziness: it just works. Although I take full advantage D's 
low level powers, my programs have mostly been I/O bound with 
huge files, so dmd's less-than ideal optimization powers are 
hidden because most threads are waiting for file system I/O.


Aside: std.parallelism and std.concurrency have been very 
helpful.


Ali


In the 1980s on our VAX 11/750, compile jobs were batch jobs 
placed in a queue. Half hour waits were not unknown. A build of 
the new o/s we were working on took around 40 mins on a 33 MHz 
386 Dell PC (later a 486!) iirc. So time for patisserie even. But 
in oractice you simply got on with other jobs, like writing new 
code that was not yet integrated, code reviews, all sorts of 
things.


Compiling the runtime library

2023-06-24 Thread Cecil Ward via Digitalmars-d-learn
Is it possible to recompile the LDC and GDC runtimes yourself so 
you can do so with the switches you desire? (eg regarding 
optimisation, release vs debug build modes.)


I think I saw a mention of something to help with this in the LDC 
docs, GDC would be a different story though.


I’d have to get hold of the code first somehow, of course.


Unused routines and inlining

2023-06-24 Thread Cecil Ward via Digitalmars-d-learn
(Apologies if I have talked about this before, but my memory is 
shot because of strong pain drugs that I’m on, and it never was 
any good before either, so I may be repeating myself.)


I’m using GDC and LDC, comparing the two, and in a medium sized 
routine that I have written pretty much every routine is inlined 
all the time. No-one takes the addresses of the routines, and 
they are not called externally to the module, marked private. (Is 
that the same as ‘static’ in C and D ?) So there’s no reason for 
the compiled copies of the function bodies to still exist. This 
makes the module unnecessarily huge with all this unused code 
just sitting there. Is there anything I can be doing about this, 
to make them go away, with appropriate configuration?


It’s a wishlist item for the compilers, to check for 
zero-usage-count in functions that are always inlined, private 
and where there’s no pointer-taking so no chance of indirect 
calls. Is that sufficient?


Re: Unused routines and inlining

2023-06-24 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 24 June 2023 at 16:55:05 UTC, Cecil Ward wrote:
(Apologies if I have talked about this before, but my memory is 
shot because of strong pain drugs that I’m on, and it never was 
any good before either, so I may be repeating myself.)


[...]


s/medium sized routine/medium-sized module/


Re: A couple of questions about arrays and slices

2023-06-24 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 24 June 2023 at 16:42:45 UTC, Cecil Ward wrote:
On Saturday, 24 June 2023 at 15:12:14 UTC, Jonathan M Davis 
wrote:

[...]


Yeah, it would take me forever to get my head around that, and 
I only want a crude toy partial parser for certain portions of 
the grammar, and the parsing code is done now. A hand-written 
recursive descent type thing mainly dealing with things like 
comments and literal string that have to be taken account of as 
they prevent hazards to naive straight string searching for 
what you want to find, as comments and eg double-quoted strings 
could have things in them that are red-herrings or the things 
that you want to find items in, depending on circumstances.


[...]


I read an article about just that good strings trick many many 
years back, and the author called it ‘a string universe’, which I 
really liked.


Re: A couple of questions about arrays and slices

2023-06-24 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 24 June 2023 at 15:12:14 UTC, Jonathan M Davis wrote:
On Saturday, June 24, 2023 8:43:00 AM MDT Cecil Ward via 
Digitalmars-d-learn wrote:
I started out looking into a number of runtime library 
routines, but in the end it seemed quicker to roll my own code 
for a crude recursive descent parser/lexer that parses part of 
D’s grammar for expressions, and (again partial grammar) 
parser for string literal expressions and so on. I find 
certain special elements and execute actions which involve 
doing the AA lookup and replacing variable names with ordinal 
numbers in decimal in the output stream. Admission: The 
parsing is the thing that has to be fast, even though again 
the size of the D language text is not likely to be huge at 
all. But 40 years ago, I came from a world with 2k RAM and 0.9 
MHz clock rates so I have developed a habit of always thinking 
about speed before I do anything, needful or not, to be 
honest. I once wrote a program that took 35 mins to evaluate 
2+2 and print out the answer, so I’m now ashamed of writing 
slow code. Those were bad days, to be honest. 4 GHz+ and ILP 
is nicer.


Well, dmd is open source (and Boost-licensed, so it doesn't 
really have any restrictions), so depending on what you're 
doing, it might make sense to just take code from that (and 
it's very fast). IIRC, it pulls some fun tricks like replacing 
identical strings with pointers to the same string so that it 
can just compare pointers.


- Jonathan M Davis


Yeah, it would take me forever to get my head around that, and I 
only want a crude toy partial parser for certain portions of the 
grammar, and the parsing code is done now. A hand-written 
recursive descent type thing mainly dealing with things like 
comments and literal string that have to be taken account of as 
they prevent hazards to naive straight string searching for what 
you want to find, as comments and eg double-quoted strings could 
have things in them that are red-herrings or the things that you 
want to find items in, depending on circumstances.


I’m trying to get my head round the differences between OSX tools 
and those for Linux relating to LDC and GDC which seems slightly 
inferior in some situations. I’m a serious professional asm 
programmer of old, before compilers were of usable output quality 
for
git-hard applications. (‘a git’ a disreputable person, colloquial 
English English. ‘git hard’ - brain-meltingly hard, like quantum 
gravity.)


Toolchain with ldc and AArch64 OSX

2023-06-24 Thread Cecil Ward via Digitalmars-d-learn
I have LDC running on an ARM Mac. If anyone else out there is an 
LDC or GDC user, could you knock up a quick shell program to 
compile and link a .d file to produce an executable ? found the 
linker but these tools are all new to me and a bit of help would 
save me a lot of trial and error and frustration as I try to find 
docs. GDC would be great too.


I have managed to achieve this before on a Raspberry Pi AArch64 
Linux Debian where the compiler can link and generate an 
executable just in integrated fashion in the one command. The OSX 
tools seem rather different however.


I’m going to try installing GDC on the Mac next, have got that 
running on the Pi too successfully.


Re: A couple of questions about arrays and slices

2023-06-24 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 24 June 2023 at 12:05:26 UTC, Jonathan M Davis wrote:
On Saturday, June 24, 2023 1:43:53 AM MDT Cecil Ward via 
Digitalmars-d-learn wrote:

On Saturday, 24 June 2023 at 07:36:26 UTC, Cecil Ward wrote:
> [...]

I just realised something, your point about altering the table 
and having to rehash, is well taken. I hadn’t considered that. 
The reason for my foolishness in failing to realise that I’m 
asking the impractical is my pattern of usage. I add all the 
entries into the mapping table and have no interest in any 
lookups until it is fully built. Then a second function starts 
to do lookups while the data remains unchanging and that usage 
pattern can be guaranteed. I could even idup it if that would 
help, as copying < 32 uints wouldn’t take forever. A typical 
value would be a mere 5 or less. I only picked 32 to be 
completely safely ott.


Well, if the key were a struct or a class, the hashing function 
would be opHash. For built-in types, the runtime has hashing 
functions that it uses. Either way, with AAs, you really don't 
worry about managing the memory, because it's completely 
outside of your control. You just put the elements in there 
using their associated keys, and if you want to try to speed it 
up after you've populated it, you use rehash so that the 
runtime can try to move the elements around within the 
container so that lookup speeds will be closer to optimal.


As such, for the most part, when dealing with AAs and worrying 
about efficiency, the question really becomes whether AAs are 
the correct solution rather than much of anything having to do 
with how you manage their memory.


With so few elements, it's also possible that using 
std.algorithm.searching.find would be faster - e.g. having a 
dynamic array of strings where the matching int is at the same 
index in a dynamic array of ints - or you could use 
std.typecons.Tuple!(string, int)[] with something like 
arr.find!(a => a[0] == key)() to find the tuple with the int 
you want.


Simply comparing a small number of strings like that might be 
faster than what goes on with hashing the string and then 
finding the corresponding element within the AA - or it might 
not be. You'd have to test that to know. The AA would 
definitely be faster with a large number of elements, but with 
a small number of elements, the algorithmic complexity doesn't 
really matter, and the extra overhad with the AA lookups could 
actually mean that the search through the dynamic array is 
faster even though it's O(n). But you can only know which is 
faster by testing it out with the actual data that you're 
dealing with.


Regardless, you need to remember that associative arrays are 
not arrays in the C sense. Rather, they're hash tables, so they 
function very differently from dynamic arrays, and the rehash 
function is the closest that you're going to get to affecting 
how the elements are laid out internally or how much memory the 
AA is using.


- Jonathan M Davis


I started out looking into a number of runtime library routines, 
but in the end it seemed quicker to roll my own code for a crude 
recursive descent parser/lexer that parses part of D’s grammar 
for expressions, and (again partial grammar) parser for string 
literal expressions and so on. I find certain special elements 
and execute actions which involve doing the AA lookup and 
replacing variable names with ordinal numbers in decimal in the 
output stream. Admission: The parsing is the thing that has to be 
fast, even though again the size of the D language text is not 
likely to be huge at all. But 40 years ago, I came from a world 
with 2k RAM and 0.9 MHz clock rates so I have developed a habit 
of always thinking about speed before I do anything, needful or 
not, to be honest. I once wrote a program that took 35 mins to 
evaluate 2+2 and print out the answer, so I’m now ashamed of 
writing slow code. Those were bad days, to be honest. 4 GHz+ and 
ILP is nicer.


Re: A couple of questions about arrays and slices

2023-06-24 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 24 June 2023 at 07:36:26 UTC, Cecil Ward wrote:
Jonathan, is it possible that I wanted one thing and got 
another? My description in the earlier post was of the _aim_ of 
the program. What I ended up with might be something else? I 
wanted an array of uints whose values are the results/outputs 
of the mapping function. Since it is keyed by strings I assumed 
that the runtime generates some kind of hash for fast lookup 
when I ask it to retrieve an entry by the string (key) 
associated with it. I assumed that in some sense the hashing 
was sort of separate with some degree of independence from the 
underlying array, if that makes sense. The lookup is just 
assumed to be fast but how it is done we don’t really care. I 
just wanted to expand the array as I did successfully elsewhere 
with reserve, as I built this structure by successive additions 
of data. I have a number of strings and the map is meant to 
output the ordinal number in which I first saw them, 
zero-based. Then I want to come back and randomly look up one 
ordinal given a string preferably with a very fast lookup. The 
number of entries can not practically be more than 30, and even 
that would be highly unusual, maybe ten is the practical limit 
in my particular case, so it’s hardly MySQL.


I just realised something, your point about altering the table 
and having to rehash, is well taken. I hadn’t considered that. 
The reason for my foolishness in failing to realise that I’m 
asking the impractical is my pattern of usage. I add all the 
entries into the mapping table and have no interest in any 
lookups until it is fully built. Then a second function starts to 
do lookups while the data remains unchanging and that usage 
pattern can be guaranteed. I could even idup it if that would 
help, as copying < 32 uints wouldn’t take forever. A typical 
value would be a mere 5 or less. I only picked 32 to be 
completely safely ott.


Re: A couple of questions about arrays and slices

2023-06-24 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 24 June 2023 at 01:28:03 UTC, Jonathan M Davis wrote:
On Friday, June 23, 2023 7:02:12 PM MDT Cecil Ward via 
Digitalmars-d-learn wrote:
I just had a fight with LDC over the following code when I 
tried out reserve. I have an associative array that maps 
strings to ‘ordinals’ ie uints that are unique, and the 
compiler hates the call to reserve.


==



struct decls_t
  {
  uintn_entries = 0;
  uint[ dstring ] ordinals;   // Associative array maps 
variable

names to ordinals
  }

static decls_t Decls;

enum NPreAllocEntries = 32;
Decls.ordinals.reserve( NPreAllocEntries );

source>(82): Error: none of the overloads of template
`object.reserve` are callable using argument types
`!()(uint[dstring], ulong)`
/opt/compiler-explorer/ldc1.32.1/ldc2-1.32.1-linux-x86_64/bin/../import/obje
ct.d(3983):Candidate is: `reserve(T)(ref T[] arr, 
size_t

newcapacity)` Compiler returned: 1


Associative arrays and dynamic arrays are completely different 
things. Associative arrays are hash tables, and reserve really 
doesn't make sense for them. reserve is for telling the GC to 
make sure that a dynamic array has at least a specific amount 
of room to grow into before the GC needs to do a reallocation 
so that the dynamic array refers to a different memory block 
with enough memory to hold the data, whereas if and when 
associative arrays have to reallocate any of their internals is 
largely implementation-defined.


Any time that you add or remove elements from an AA, it might 
reallocate some of its internals depending on its current state 
and what the key of the element is - and that could be 
different between different compiler releases (though it's 
unlikely to change very often, since I don't think that the AA 
implementation gets messed with much).


You can use the rehash function on AAs to tell the GC to try to 
reorder how it's structured all of its buckets so that lookups 
are more efficient with the data that's currently in there, and 
you can call clear to remove all its elements, but in general, 
you don't do much to manage an AA's memory. It's a much more 
complicated data structure than an array.


https://dlang.org/spec/hash-map.html

- Jonathan M Davis


Jonathan, is it possible that I wanted one thing and got another? 
My description in the earlier post was of the _aim_ of the 
program. What I ended up with might be something else? I wanted 
an array of uints whose values are the results/outputs of the 
mapping function. Since it is keyed by strings I assumed that the 
runtime generates some kind of hash for fast lookup when I ask it 
to retrieve an entry by the string (key) associated with it. I 
assumed that in some sense the hashing was sort of separate with 
some degree of independence from the underlying array, if that 
makes sense. The lookup is just assumed to be fast but how it is 
done we don’t really care. I just wanted to expand the array as I 
did successfully elsewhere with reserve, as I built this 
structure by successive additions of data. I have a number of 
strings and the map is meant to output the ordinal number in 
which I first saw them, zero-based. Then I want to come back and 
randomly look up one ordinal given a string preferably with a 
very fast lookup. The number of entries can not practically be 
more than 30, and even that would be highly unusual, maybe ten is 
the practical limit in my particular case, so it’s hardly MySQL.


Re: A couple of questions about arrays and slices

2023-06-23 Thread Cecil Ward via Digitalmars-d-learn

On Thursday, 22 June 2023 at 05:21:52 UTC, Cecil Ward wrote:
On Thursday, 22 June 2023 at 01:44:22 UTC, Jonathan M Davis 
wrote:
On Wednesday, June 21, 2023 7:05:28 PM MDT Paul Backus via 
Digitalmars-d-learn wrote:

[...]


To add to that, it _has_ to know the element type, because 
aside from anything related to a type's size, it bit-blits the 
type's init value onto the new elements when it increases the 
length of the dynamic array.


You'd probably be dealing with bytes if you were explicitly 
asking for memory and the like (e.g. with malloc), but a 
dynamic array is properly typed, and everything you do with it 
in @safe code is going to deal with it as properly typed. For 
it to be otherwise would require @system casts.


- Jonathan M Davis


Thankyou Jonathan!


I just had a fight with LDC over the following code when I tried 
out reserve. I have an associative array that maps strings to 
‘ordinals’ ie uints that are unique, and the compiler hates the 
call to reserve.


==



struct decls_t
{
uintn_entries = 0;
	uint[ dstring ]		ordinals;	// Associative array maps variable 
names to ordinals

}

static decls_t Decls;

enum NPreAllocEntries = 32;
Decls.ordinals.reserve( NPreAllocEntries );

source>(82): Error: none of the overloads of template 
`object.reserve` are callable using argument types 
`!()(uint[dstring], ulong)`

/opt/compiler-explorer/ldc1.32.1/ldc2-1.32.1-linux-x86_64/bin/../import/object.d(3983):
Candidate is: `reserve(T)(ref T[] arr, size_t newcapacity)`
Compiler returned: 1



Re: A couple of questions about arrays and slices

2023-06-21 Thread Cecil Ward via Digitalmars-d-learn

On Thursday, 22 June 2023 at 01:44:22 UTC, Jonathan M Davis wrote:
On Wednesday, June 21, 2023 7:05:28 PM MDT Paul Backus via 
Digitalmars-d-learn wrote:

[...]


To add to that, it _has_ to know the element type, because 
aside from anything related to a type's size, it bit-blits the 
type's init value onto the new elements when it increases the 
length of the dynamic array.


You'd probably be dealing with bytes if you were explicitly 
asking for memory and the like (e.g. with malloc), but a 
dynamic array is properly typed, and everything you do with it 
in @safe code is going to deal with it as properly typed. For 
it to be otherwise would require @system casts.


- Jonathan M Davis


Thankyou Jonathan!


Re: A couple of questions about arrays and slices

2023-06-21 Thread Cecil Ward via Digitalmars-d-learn

On Thursday, 22 June 2023 at 01:05:28 UTC, Paul Backus wrote:

On Thursday, 22 June 2023 at 00:10:19 UTC, Cecil Ward wrote:
Is .reserve()’s argument scaled by the entry size after it is 
supplied, that is it is quoted in elements or is it in bytes? 
I’m not sure whether the runtime has a knowledge of the 
element type so maybe it doesn’t know anything about scale 
factors, not sure.


length, reserve, and capacity all use the same unit, which is 
elements.


reserve passes a TypeInfo instance to the runtime so that it 
knows the size of the elements. You can see the implementation 
here:


https://github.com/dlang/dmd/blob/v2.104.0/druntime/src/object.d#L3910


Many thanks Paul, I should have found that!


Re: A couple of questions about arrays and slices

2023-06-21 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 21 June 2023 at 15:48:56 UTC, H. S. Teoh wrote:
On Wed, Jun 21, 2023 at 02:09:26AM +, Cecil Ward via 
Digitalmars-d-learn wrote:

First is an easy one:

1.) I have a large array and a sub-slice which I want to set 
up to be pointing into a sub-range of it. What do I write if I 
know the start and end indices ? Concerned about an off-by-one 
error, I have start_index and past_end_index (exclusive).


array[start_idx .. one_past_end_idx]


2.) I have a dynamic array and I wish to preinitialise its 
alloc cell to be a certain large size so that I don’t need to 
reallocate often initially. I tell myself that I can set the 
.length property. Is that true?


You can use `array.reserve(preinitSize);`.


2a.) And what happens when the cell is extended, is the 
remainder zero-filled or remaining full of garbage, or is the 
size of the alloc cell something separate from the dynamic 
array’s knowledge of the number of valid elements in it ?


The size of the allocated cell is managed by druntime. On the 
user code side, all you know is the slice (start pointer + 
length).  The allocated region outside the current array length 
is not initialized.  Assigning to array.length initializes the 
area that the array occupies after the length has been extended.



T


Is .reserve()’s argument scaled by the entry size after it is 
supplied, that is it is quoted in elements or is it in bytes? I’m 
not sure whether the runtime has a knowledge of the element type 
so maybe it doesn’t know anything about scale factors, not sure.


Re: A couple of questions about arrays and slices

2023-06-21 Thread Cecil Ward via Digitalmars-d-learn
On Wednesday, 21 June 2023 at 04:52:06 UTC, Jonathan M Davis 
wrote:
On Tuesday, June 20, 2023 8:09:26 PM MDT Cecil Ward via 
Digitalmars-d-learn wrote:

[...]


When slicing, the end index is exclusive. e.g.

[...]


Actually concerning the garbage, I was rather hoping that it 
_would_ be garbage so as to avoid the cost of a zero-fill in time 
and also possibly in cache pollution, unless it uses the 
non-temporal cache-friendliness management tech that is found on 
eg x86.


Re: A couple of questions about arrays and slices

2023-06-21 Thread Cecil Ward via Digitalmars-d-learn
On Wednesday, 21 June 2023 at 04:52:06 UTC, Jonathan M Davis 
wrote:
On Tuesday, June 20, 2023 8:09:26 PM MDT Cecil Ward via 
Digitalmars-d-learn wrote:

[...]


When slicing, the end index is exclusive. e.g.

[...]


Thankyou to both posters for your exceptionally helpful and 
generous replies, which will serve as a help to others if I made 
the title searchable. I need to look at the appended and try to 
find some (more) example code.


A couple of questions about arrays and slices

2023-06-20 Thread Cecil Ward via Digitalmars-d-learn

First is an easy one:

1.) I have a large array and a sub-slice which I want to set up 
to be pointing into a sub-range of it. What do I write if I know 
the start and end indices ? Concerned about an off-by-one error, 
I have start_index and past_end_index (exclusive).


2.) I have a dynamic array and I wish to preinitialise its alloc 
cell to be a certain large size so that I don’t need to 
reallocate often initially. I tell myself that I can set the 
.length property. Is that true?


2a.) And what happens when the cell is extended, is the remainder 
zero-filled or remaining full of garbage, or is the size of the 
alloc cell something separate from the dynamic array’s knowledge 
of the number of valid elements in it ?


Re: How does D’s ‘import’ work?

2023-06-20 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 19 June 2023 at 16:24:03 UTC, rempas wrote:

On Monday, 19 June 2023 at 12:48:26 UTC, Cecil Ward wrote:


If I have sources to all the library routines, not libraries 
or .obj files. I am simply completely ignorant about the D 
tools including DUB, so off to do some reading. I’ve just been 
seeing how good LDC and GDC are, and the answer is extremely, 
especially LDC, which perhaps has a slight edge in code 
generation quality. I haven’t looked at AAarch64 code yet, 
only AMD64. Very impressed with all the work!


Of course, DMD uses it's own custom backend so it's only fair 
to not expect for it to have the same runtime performance and 
optimizations as the other two compilers than use LLVM and GCC. 
If you only use x86_64, DMD will be amazing for your debug 
cycles!


I’ve never used DMD. I don’t support that it will run on Aarch64. 
I’m running ldc on an ARM M2 Mac OSX. Also on x86-64 VMs at 
Godbolt.org but I must get access to an x86-64 box myself.


Re: How does D’s ‘import’ work?

2023-06-20 Thread Cecil Ward via Digitalmars-d-learn

On Sunday, 18 June 2023 at 21:51:14 UTC, Jonathan M Davis wrote:
On Sunday, June 18, 2023 2:24:10 PM MDT Cecil Ward via 
Digitalmars-d-learn wrote:
I wasn’t intending to use DMD, rather ldc if possible or GDC 
because of their excellent optimisation, in which DMD seems 
lacking, is that fair? (Have only briefly looked at dmd+x86 
and haven’t given DMD’s back end a fair trial.)


In general, dmd is fantastic for its fast compilation speed. 
So, it works really well for developing whatever software 
you're working on (whereas ldc and gdc are typically going to 
be slower at compiling). And depending on what you're doing, 
the code is plenty fast. However, if you want to maximize the 
efficiency of your code, then you definitely want to be 
building the binaries that you actually use or release with ldc 
or gdc.


- Jonathan M Davis


Good point. I’m used to slow compilers on fast machines and 
compiling gives me an excuse for more coffee and possibly fruity 
buns. I’m incredibly impressed with LDC, GDC slightly less so, as 
it sometimes calls runtime library routines where Ldc doesn’t. 
Like in things to do with arrays, for one example.


I hate calls to runtime library routines unless they are really 
substantial, mind you many calls to a modest-sized routine can 
get you a hotter cache, and even micro-op cache, and keep the 
whole code size down so as to improve cache overload or even 
pollution.


Re: How does D’s ‘import’ work?

2023-06-19 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 19 June 2023 at 08:46:31 UTC, rempas wrote:

On Sunday, 18 June 2023 at 20:17:50 UTC, Cecil Ward wrote:


target.obj: target.c include1.h include2.h cc.exe
cc target.c

and you either have to pray that you have kept the list of .h 
files that are mentioned inside target.c and other .h files 
referenced recursively from within these .h files etc. I 
listed the compiler as a dependency too, and I should really 
have a pseudo-target somehow that depends on the nature of the 
command line because changing the command line affects the 
generated code. If you have an automaking compiler that will 
generate the list of .h files then that’s so, so much safer.


First of all, If we are talking about C files, D can import and 
compile them so you don't even need a Makefile! Now, if you 
need to compile C++ files and then either link or create a 
library (and link with it from the D project), then you can 
just run Dub in the end of the job in your make file! You can 
then have a variable called `DUB_FLAGS` in your Makefile and 
this is where the arguments that will be passed for the Dub 
will be. Will this be good enough for you?


If I have sources to all the library routines, not libraries or 
.obj files. I am simply completely ignorant about the D tools 
including DUB, so off to do some reading. I’ve just been seeing 
how good LDC and GDC are, and the answer is extremely, especially 
LDC, which perhaps has a slight edge in code generation quality. 
I haven’t looked at AAarch64 code yet, only AMD64. Very impressed 
with all the work!


Re: How does D’s ‘import’ work?

2023-06-18 Thread Cecil Ward via Digitalmars-d-learn

On Thursday, 8 June 2023 at 05:11:04 UTC, Ali Çehreli wrote:

On 6/7/23 21:17, Cecil Ward wrote:

> I was thinking about the situation in C where I have a rule
in a make
> file that lists the .h files as well as the .c all as
dependencies in
> creating an object file.

dmd's -makedeps command line switch should be helpful there. (I 
did not use it.)


Ali


I wasn’t intending to use DMD, rather ldc if possible or GDC 
because of their excellent optimisation, in which DMD seems 
lacking, is that fair? (Have only briefly looked at dmd+x86 and 
haven’t given DMD’s back end a fair trial.)


Re: How does D’s ‘import’ work?

2023-06-18 Thread Cecil Ward via Digitalmars-d-learn

On Sunday, 18 June 2023 at 17:34:51 UTC, rempas wrote:

On Thursday, 8 June 2023 at 04:17:20 UTC, Cecil Ward wrote:
I was thinking about the situation in C where I have a rule in 
a make file that lists the .h files as well as the .c all as 
dependencies in creating an object file.


I don't think I'm aware of what you mean with "lists .h and .c 
files". Could you provide a small makefile that does that so I 
can run and examine?


target.obj: target.c include1.h include2.h cc.exe
cc target.c

and you either have to pray that you have kept the list of .h 
files that are mentioned inside target.c and other .h files 
referenced recursively from within these .h files etc. I listed 
the compiler as a dependency too, and I should really have a 
pseudo-target somehow that depends on the nature of the command 
line because changing the command line affects the generated 
code. If you have an automaking compiler that will generate the 
list of .h files then that’s so, so much safer.


Re: SIMD c = a op b

2023-06-17 Thread Cecil Ward via Digitalmars-d-learn

On Sunday, 18 June 2023 at 04:54:08 UTC, Cecil Ward wrote:

Is it true that this doesn’t work (in either branch)?

float4 a,b;
static if (__traits(compiles, a/b))
c = a / b;
else
c[] = a[] / b[];

I tried it with 4 x 64-bit ulongs in a 256-bit vector instead.
Hoping I have done things correctly, I got an error message 
about requiring a destination variable as in c = a op b where I 
tried simply "return a / b;" In the else branch, I got a type 
conversion error. Is that because a[] is an array of 256-bit 
vectors, in the else case, not an array of ulongs?


Correction I should have written ‘always work’ - I just copied 
the example straight from the language documentation for simd and 
adapted it to use ulongs and a wider vector.


I was using GDC.


Re: Como puedo hacer funciones asincronas?

2023-06-17 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 17 June 2023 at 22:05:37 UTC, Danico wrote:
hola gente, quisiera saber como es que puedo hacer funciones 
asincronas.

`
#!/usr/bin/env dmd
import std;
import std.stdio;
import std.concurrency;
//import archivo2;

alias print = writeln;

void main () {

auto tarea1 = spawn();
auto tarea2 = spawn();

print("realizando tareas ");


}

void saludo () {
print("hola");
}

async saludo2 () {
print("hola2");
}

`


This is something I have wanted to achieve also.


Parser

2023-06-14 Thread Cecil Ward via Digitalmars-d-learn
I’m thinking that I might had to end up writing a partial, rather 
rough parser for parts of the D language. Could I get some 
suggestions for help that I might find in the way of software 
components? D has a very powerful regex module, I believe.


I have been writing inline asm library routines for GDC as a 
learning exercise and unfortunately I can’t build them under LDC 
because LDC does not yet offer full support for the GCC in-line 
asm grammar, specifically named in-asm arguments such as " mov 
%[dest], %[src]" - where you see the names enclosed in [ ]. I’m 
thinking that I might have to fix this deficiency myself. There’s 
no way that I can enhance LDC myself as I wouldn’t even know 
where to start.


I could pre-process the string expressions used in inline asm so 
that LDC could understand an alternative easier grammar, one 
where there are numbers instead of "[names]", eg "%0" instead of 
the meaningful "%[dest]". It seems that the compilers take string 
_expressions_ everywhere rather than just simple literal strings.


Can I generate fragments of D and inject them into the rest of 
the code using mixin? Not really sure how to use it.


There are three string expressions involved: the string 
containing the asm, which needs to be scanned for %[ names ], and 
these need to be replaced with numbers in order of occurrence of 
declarations of the names, then an outputs section and an inputs 
section which can both contain declarations of these names, eg ‘: 
[ dest ] "=r" ( d-expression ) ,’ … ‘: [ src ]’…. The arbitrary 
fragment of D in d-expression can unfortunately be anything, and 
there’s no way I can write a full D lexer/parser to scan that 
properly,  but luckily I just have to pass over it to find its 
terminator which is either a ‘,’ or a ‘:’. (There might be a case 
where there is a ‘;’ as a terminator instead of a ‘:’, I’m not 
sure if that’s permitted in the grammar immediately after the 
inputs section.


But having to parse all the types of strings and operators in a 
string-expression is hard enough. I will also have to deal with 
all the possible comment types wherever they can occur, which is 
all over the place within, before and after these expressions.


Any tips, modules that I could use would be most welcome. I’m 
very much out of my depth here.


Re: byte and short data types use cases

2023-06-10 Thread Cecil Ward via Digitalmars-d-learn

On Sunday, 11 June 2023 at 00:05:52 UTC, H. S. Teoh wrote:
On Sat, Jun 10, 2023 at 09:58:12PM +, Cecil Ward via 
Digitalmars-d-learn wrote:

On Friday, 9 June 2023 at 15:07:54 UTC,



[...]

On contemporary machines, the CPU is so fast that memory access 
is a much bigger bottleneck than processing speed. So unless an 
operation is being run hundreds of thousands of times, you're 
not likely to notice the difference. OTOH, accessing memory is 
slow (that's why the memory cache hierarchy exists). So utf8 is 
actually advantageous here: it fits in a smaller space, so it's 
faster to fetch from memory; more of it can fit in the CPU 
cache, so less DRAM roundtrips are needed. Which is faster.  
Yes you need extra processing because of the variable-width 
encoding, but it happens mostly inside the CPU, which is fast 
enough that it generally outstrips the memory roundtrip 
overhead. So unless you're doing something *really* complex 
with the utf8 data, it's an overall win in terms of 
performance. The CPU gets to do what it's good at -- running 
complex code -- and the memory cache gets to do what it's good 
at: minimizing the amount of slow DRAM roundtrips.




I completely agree with H. S. Teoh. That is exactly what I was 
going to say. The point is that considerations like this have to 
be thought through carefully and width of types really does 
matter in the cases brought up.


But outside these cases, as I said earlier, stick to uint, size_t 
and ulong, or uint32_t and uint64_t if exact size is vital, but 
do also check out the other std.stdint types too as very 
occasionally they are needed.




Re: byte and short data types use cases

2023-06-10 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 10 June 2023 at 21:58:12 UTC, Cecil Ward wrote:

On Friday, 9 June 2023 at 15:07:54 UTC, Murloc wrote:

On Friday, 9 June 2023 at 12:56:20 UTC, Cecil Ward wrote:

[...]


Is this some kind of property? Where can I read more about 
this?


My last example is comms. Protocol headers need economical narrow 
data types because of efficiency, it’s all about packing as much 
user data as possible into each packet and fatter, longer headers 
reduce the amount of user data as the total has a hard limit on 
it. A pair of headers totalling 40 bytes in IPv4+TCP takes up 
nearly 3% of the total length allowed, so that’s a ~3% speed 
loss, as the headers are just dead weight. So here narrow types 
help comms speed.


Re: byte and short data types use cases

2023-06-10 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 9 June 2023 at 15:07:54 UTC, Murloc wrote:

On Friday, 9 June 2023 at 12:56:20 UTC, Cecil Ward wrote:

On Friday, 9 June 2023 at 11:24:38 UTC, Murloc wrote:

If you have four ubyte variables in a struct and then
an array of them, then you are getting optimal memory usage.


Is this some kind of property? Where can I read more about this?

So you can optimize memory usage by using arrays of things 
smaller than `int` if these are enough for your purposes, but 
what about using these instead of single variables, for example 
as an iterator in a loop, if range of such a data type is 
enough for me? Is there any advantages on doing that?


A couple of other important use-cases came to me. The first one 
is unicode which has three main representations, utf-8 which is a 
stream of bytes each character can be several bytes, utf-16 where 
a character can be one or rarely two 16-bit words, and utf32 - a 
stream of 32-bit words, one per character. The simplicity of the 
latter is a huge deal in speed efficiency, but utf32 takes up 
almost four times as memory as utf-8 for western european 
languages like english or french. The four-to-one ratio means 
that the processor has to pull in four times the amount of memory 
so that’s a slowdown, but on the other hand it is processing the 
same amount of characters whichever way you look at it, and in 
utf8 the cpu is having to parse more bytes than characters unless 
the text is entirely ASCII-like.


The second use-case is about SIMD. Intel and AMD x86 machines 
have vector arithmetic units that are either 16, 32 or 64 bytes 
wide depending on how recent the model is. Taking for example a 
post-2013 Intel Haswell CPU, which has 32-byte wide units, if you 
choose smaller width data types you can fit more in the vector 
unit - that’s how it works, and fitting in more integers or 
floating point numbers of half width means that you can process 
twice as many in one instruction. On our Haswell that means four 
doubles or four quad words, or eight 32-bit floats or 32-bit 
uint32_ts, and similar doubling s’s for uint16_t. So here width 
economy directly relates to double speed.


Re: byte and short data types use cases

2023-06-09 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 9 June 2023 at 15:07:54 UTC, Murloc wrote:

On Friday, 9 June 2023 at 12:56:20 UTC, Cecil Ward wrote:

On Friday, 9 June 2023 at 11:24:38 UTC, Murloc wrote:

If you have four ubyte variables in a struct and then
an array of them, then you are getting optimal memory usage.


Is this some kind of property? Where can I read more about this?

So you can optimize memory usage by using arrays of things 
smaller than `int` if these are enough for your purposes, but 
what about using these instead of single variables, for example 
as an iterator in a loop, if range of such a data type is 
enough for me? Is there any advantages on doing that?


Read up on ‘structs’ and the ‘align’ attribute in the main d 
docs, on this website. Using smaller fields in a struct that is 
in memory saves RAM if there is an array of such structs. Even in 
the case where there is only one struct, let’s say that you are 
returning a struct by value from some function. If the struct is 
fairly small in total, and the compiler is good (ldc or gdc, not 
dmd - see godbolt.org) then the returned struct can fit into a 
register sometimes, rather than being placed in RAM, when it is 
returned to the function’s caller. Yesterday I returned a struct 
containing four uint32_t fields from a function and it came back 
to the caller in two 64-bit registers, not in RAM. Clearly using 
smaller fields if possible might make it possible for the whole 
struct to be under the size limit for being returned in registers.


As for your question about single variables. The answer is very 
definitely no. Rather, the opposite: always use primary 
CPU-‘natural’ types, widths that are most natural to the 
processor in question. 64-bit cpus will sometimes favour 32-bit 
types an example being x86-64/AMD64, where code handling 32-bit 
ints generates less code (saves bytes in the code segment) but 
the speed and number of instructions is the same on such a 64-bit 
processor where you’re dealing with 32- or 64- bit types. Always 
use size_t for index variables into arrays or the size of 
anything in bytes, never int or uint. On a 64-bit machine such as 
x86-64, size_t is 64-bit, not 32. By using int/uint when you 
should have used size_t you could in theory get a very rare bug 
when dealing with eg file sizes or vast amounts of (virtual) 
memory, say bigger than 2GB (int limit) or 4GB (uint limit) when 
the 32-bit types overflow. There is also a ptrdiff_t which is 
64-bit on a 64-bit cpu, probably not worth bothering with as its 
raison d’être was historical (early 80s 80286 segmented 
architecture, before the 32-bit 386 blew it away).


Re: byte and short data types use cases

2023-06-09 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 9 June 2023 at 11:24:38 UTC, Murloc wrote:
Hi, I was interested why, for example, `byte` and `short` 
literals do not have their own unique suffixes (like `L` for 
`long` or `u` for `unsigned int` literals) and found the 
following explanation:


- "I guess short literal is not supported solely due to the 
fact that anything less than `int` will be "promoted" to `int` 
during evaluation. `int` has the most natural size. This is 
called integer promotion in C++."


Which raised another question: since objects of types smaller 
than `int` are promoted to `int` to use integer arithmetic on 
them anyway, is there any point in using anything of integer 
type less than `int` other than to limit the range of values 
that can be assigned to a variable at compile time? Are these 
data types there because of some historical reasons (maybe 
`byte` and/or `short` were "natural" for some architectures 
before)?


People say that there is no advantage for using `byte`/`short` 
type for integer objects over an int for a single variable, 
however, as they say, this is not true for arrays, where you 
can save some memory space by using `byte`/`short` instead of 
`int`. But isn't any further manipulations with these array 
objects will produce results of type `int` anyway? Don't you 
have to cast these objects over and over again after 
manipulating them to write them back into that array or for 
some other manipulations with these smaller types objects? Or 
is this only useful if you're storing some array of constants 
for reading purposes?


Some people say that these promoting and casting operations in 
summary may have an even slower overall effect than simply 
using int, so I'm kind of confused about the use cases of these 
data types... (I think that my misunderstanding comes from not 
knowing how things happen at a slightly lower level of 
abstractions, like which operations require memory allocation, 
which do not, etc. Maybe some resource recommendations on 
that?) Thanks!


For me there are two use cases for using byte and short, ubyte 
and ushort.


The first is simply to save memory in a large array or neatly fit 
into a ‘hole’ in a struct, say next to a bool which is also a 
byte. If you have four ubyte variables in a struct and then an 
array of them, then you are getting optimal memory usage. In the 
x86 for example the casting operations for ubyte to uint use 
instructions that have zero added cost compared to a normal uint 
fetch. And casting to a ubyte generates no code at all. So the 
costs of casting in total are zero.


The second use-case is where you need to interface to external 
specifications that deman uint8_t (ubyte), or uint16_t (ushort) 
where I am using the standard definitions from std.stdint. These 
types are the in C. If you are interfacing to externally defined 
struct in data structures in ram or in messages, that’s one 
example. The second example is where you need to interface to 
machine code that has registers or operands of 8-bit or 16-bit 
types. I like to use the stdint types for the purposes of 
documentation as it rams home the point that these are truly 
fixed width types and can not change. (And I do know that in D, 
unlike C, int, long etc are of defined fixed widths. Since C 
doesn’t have those guarantees that’s why the C stdint.h is needed 
in C too.) As well as machine code, we could add other high-level 
languages where interfaces are defined in the other language and 
you have to hope that the other language’s type widths don’t 
change.


Re: How does D’s ‘import’ work?

2023-06-07 Thread Cecil Ward via Digitalmars-d-learn

On Friday, 2 June 2023 at 12:07:09 UTC, rempas wrote:

On Thursday, 1 June 2023 at 03:47:00 UTC, Cecil Ward wrote:


I have another question if I may, what do we do about getting 
makefiles right given that we have imports ?


What do you mean with that? Give some more info please!


I was thinking about the situation in C where I have a rule in a 
make file that lists the .h files as well as the .c all as 
dependencies in creating an object file.


Re: Indenting standards religions K, whitesmiths etc

2023-06-01 Thread Cecil Ward via Digitalmars-d-learn

On Thursday, 1 June 2023 at 09:37:43 UTC, Dukc wrote:

On Wednesday, 31 May 2023 at 16:24:38 UTC, Cecil Ward wrote:
I wanted to ask how some of the leaders of our group feel 
about D indentation standards. `i realise that this causes 
some religious fervour in C. I could be in trouble here 
because in all my years at work, we never used K & R ‘one true 
brace style’ indenting, with the house style I’m used to being 
more like whitesmiths. Wikipedia explains this better. 
Something like the following below.


So my question: would I get lynched for the following? (below)


Check out this module from me: 
https://github.com/dukc/nuklearbrowser/blob/master/source/nuklearbrowser.d


Plus similar style in most of my posts and bug reports. I'm 
still alive :D.


Your code is your code. There, you may do as you wish. You have 
to aknowledge that an esoteric style may make it more difficult 
to read for some, but we're not lynching people for other 
factors of code readability either. Brace style is no different.


Plus, what brace style is considered readable by the majority 
is a culture issue. There has to be some way to challege the 
established culture. If you don't exercise your power to code 
as you wish, someone will make your choice for you. Coding 
culture, or even culture in general, cannot develop if people 
never challege the present status quo.


When you're coding with others, though, then you should obey 
the style guideline of that project if there is one. Even there 
you're as entitled as anyone for an opinion what the style 
policy should be (and to whether there should be style policy 
at all), but you then should (usually) obey the decision 
regardless whether it's the one you were advocating for.


I wonder how much work it would be to write a D pretty printer / 
beautifier. Doing things such as lining up parameters or comments 
and breaking and re-wrapping comments etc if necessary because of 
the changes in whitespace.


I’ve no idea what the ‘official story’ is with nested functions. 
I have some experience with that because I used to write Pascal 
(on a Z80 box and on a VAX), and that feature is like the return 
of an old friend, I love it so much and for me it’s quite a 
serious advantage over C.


I’m always guilty of overcommenting, for various reasons although 
I’m not guilt of the likes of /* add 1 to x */!  ;-) It’s partly 
because I have a shocking memory and maintenance becomes 
literally impossible for me, for me just as important I want the 
comments to spell out original intent, not the implementation 
choices, so if you see later that the two don’t match then you’ve 
spotted the bug.


Many people comment in a very minimal way which makes the code 
look neat.


I did sort of find an /* add 1 to x */ though as it was 
explaining and giving a caveat about GCC in-line asm constraints, 
and the comment saved me having to go and look things up in the 
bible.


Re: Indenting standards religions K, whitesmiths etc

2023-06-01 Thread Cecil Ward via Digitalmars-d-learn

On Thursday, 1 June 2023 at 09:37:43 UTC, Dukc wrote:

On Wednesday, 31 May 2023 at 16:24:38 UTC, Cecil Ward wrote:
I wanted to ask how some of the leaders of our group feel 
about D indentation standards. `i realise that this causes 
some religious fervour in C. I could be in trouble here 
because in all my years at work, we never used K & R ‘one true 
brace style’ indenting, with the house style I’m used to being 
more like whitesmiths. Wikipedia explains this better. 
Something like the following below.


So my question: would I get lynched for the following? (below)


Check out this module from me: 
https://github.com/dukc/nuklearbrowser/blob/master/source/nuklearbrowser.d


Plus similar style in most of my posts and bug reports. I'm 
still alive :D.


Your code is your code. There, you may do as you wish. You have 
to aknowledge that an esoteric style may make it more difficult 
to read for some, but we're not lynching people for other 
factors of code readability either. Brace style is no different.


Plus, what brace style is considered readable by the majority 
is a culture issue. There has to be some way to challege the 
established culture. If you don't exercise your power to code 
as you wish, someone will make your choice for you. Coding 
culture, or even culture in general, cannot develop if people 
never challege the present status quo.


When you're coding with others, though, then you should obey 
the style guideline of that project if there is one. Even there 
you're as entitled as anyone for an opinion what the style 
policy should be (and to whether there should be style policy 
at all), but you then should (usually) obey the decision 
regardless whether it's the one you were advocating for.


Agree completely. You are not a criminal though because your 
closing braces are not indented out with the block they’re 
closing as I do.


I find K hard to read even though we see it everywhere, or 
variants of it. I do wonder if my style in that earlier post 
hurts normal people’s eyeballs a lot. ;-)


I’m told that Irish speakers can’t understand Scottish Gaelic on 
the radio a native speaker said to me that ‘it’s just a noise’. 
But as a ScG learner myself I can understand some spoken Irish 
even though I’ve never really studied the modern language (only 
the stuff of more that 1100 yrs ago.) So the pain isn’t 
symmetrical.


Re: How does D’s ‘import’ work?

2023-05-31 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 31 May 2023 at 18:43:52 UTC, Cecil Ward wrote:
Is there an explanation of how D’s ‘import’ works somewhere? 
I’m trying to understand the comparison with the inclusion of 
.h files, similarities if any and differences with the process.


I have another question if I may, what do we do about getting 
makefiles right given that we have imports ?


Re: How does D’s ‘import’ work?

2023-05-31 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 31 May 2023 at 18:56:02 UTC, H. S. Teoh wrote:
On Wed, May 31, 2023 at 06:43:52PM +, Cecil Ward via 
Digitalmars-d-learn wrote:
Is there an explanation of how D’s ‘import’ works somewhere? 
I’m trying to understand the comparison with the inclusion of 
.h files, similarities if any and differences with the process.


Unlike C's #include, `import` does NOT paste the contents of 
the imported file into the context of `import`, like #include 
would do. Instead, it causes the compiler to load and parse the 
imported file, placing the parsed symbols into a separate 
symbol table dedicated for that module (in D, a file == a 
module). These symbols are then pulled into the local symbol 
table so that they become available to code containing the 
import declaration.


(There's a variation, `static import`, that does the same thing 
except the last step of pulling symbols into the local symbol 
table. So the symbols will not "pollute" the current namespace, 
but are still accessible via their fully-qualified name (FQN), 
i.e., by the form `pkg.mod.mysymbol`, for a symbol `mysymbol` 
defined in the module `pkg.mod`, which in turn is a module 
under the package `pkg`.)


For more information:

https://tour.dlang.org/tour/en/basics/imports-and-modules
https://dlang.org/spec/module.html


T


Thank you so very much for the links and for your generous help. 
Some C compilers used to have a thing called ‘precompiled 
headers’, potential source of trouble and ai always felt uneasy 
about it rightly or wrongly.


It’s great that D has got rid of header file includes though, 
they were ridiculously painful. I used to use the automake 
feature that was built into the JPI C compiler at work which took 
care of all the .h dependencies so you no longer had to worry 
about it. And you only loaded the compiler from disk and started 
it up once as it stayed in memory handling all the C parts of a 
make.




Re: Indenting standards religions K, whitesmiths etc

2023-05-31 Thread Cecil Ward via Digitalmars-d-learn
On Wednesday, 31 May 2023 at 22:06:50 UTC, Ernesto Castellotti 
wrote:

On Wednesday, 31 May 2023 at 16:24:38 UTC, Cecil Ward wrote:
I wanted to ask how some of the leaders of our group feel 
about D indentation standards. `i realise that this causes 
some religious fervour in C. I could be in trouble here 
because in all my years at work, we never used K & R ‘one true 
brace style’ indenting, with the house style I’m used to being 
more like whitesmiths. Wikipedia explains this better. 
Something like the following below.


[...]



Excuse me but for me the only style I like is the K
I can accept Allman but the rest is heretical to me ;-) don't 
worry, just a joke


Is there even such as thing as a pretty-printer / beautifier for 
D ? Has anyone adapted one ?


`it might save me from a lynch mob. :-) :-)


How does D’s ‘import’ work?

2023-05-31 Thread Cecil Ward via Digitalmars-d-learn
Is there an explanation of how D’s ‘import’ works somewhere? I’m 
trying to understand the comparison with the inclusion of .h 
files, similarities if any and differences with the process.


Indenting standards religions K, whitesmiths etc

2023-05-31 Thread Cecil Ward via Digitalmars-d-learn
I wanted to ask how some of the leaders of our group feel about D 
indentation standards. `i realise that this causes some religious 
fervour in C. I could be in trouble here because in all my years 
at work, we never used K & R ‘one true brace style’ indenting, 
with the house style I’m used to being more like whitesmiths. 
Wikipedia explains this better. Something like the following 
below.


So my question: would I get lynched for the following? (below)

And can anyone recommend a beautifier / pretty printer tool for D 
that is customisable to your house style if that is a thing 
that’s needed? I assume I would need that if I were to donate 
code, unless some helpful recipient would run such a tool on .d 
files received.


—

pure nothrow etc
T
foo( T, T2 )(
in T param x,
in T2 param y
)
if ( template-qualification-whatever )
in {
static assert( … );
}
out ( ret )
{
…
assert( test ret );
}
do   {
blah
if ( test ) {
…
if-body
…
}
back to main block
…
…
} /* end of function, notice the indent level stays out 
with the content */


Re: Code duplication where you wish to have a routine called with either immutable or mutable arguments

2023-05-31 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 31 May 2023 at 09:14:49 UTC, Dom DiSc wrote:

On Wednesday, 31 May 2023 at 03:29:33 UTC, Cecil Ward wrote:
I have to admit that I don’t really understand immutable. I 
have an idea that it could mean that an object has an address 
in ROM, so its value will never change. Maybe const doesn’t 
give you such a strong guarantee, disallows ‘you’ from 
modifying it but others might do so, but who knows.
There are two perspectives: that of the value handed to a 
function and that of the function taking the value.
"immutable" (or "mutable") is a property of the value, "const" 
is a property of the function.
If the function can work with mutable values, but in fact 
doesn't mutate them itself, it could also work with immutable 
values. The fact that others could modify your "const" value 
doesn't matter for immutable values, because they of course 
can't be modified by others. For the function it doesn't 
matter, because it only guarantees not to modify it itself, 
don't care about what other can or can't do.



Without a guarantee as strong as the first idea I can’t really
understand how const can work properly. "You treat it as const
so do not modify it, but it might not be eternally fixed and
unchanging" that doesn’t seem to have enough value to me.

Why? What guarantee are you missing?
Your function can work with mutable data, so you don't care if 
it can be modified also by others.
Now it happens that you doesn't modify the data. So why 
shouldn't you be able to work on data that guarantees that it 
also will not be changed by others? You don't care for such 
modification anyway.


The meaning of "immutable" is: I cannot be modified. Not by you 
and not by anybody else. It's a property of a value.
The meaning of "mutable" is: I can be modified by anybody. Work 
with me only if that is ok for you. It's a property of a value.
The meaning of "const" is: I don't care if others modify the 
data or not, I won't modify it myself. It's a property of a 
function.


Dom, you explain it well. I’m just too stupid. Literally, as I’m 
on strong pain drugs all the time, so things are a bit fuzzy. As 
a professional C programmer for some years, I understood the word 
const and used it all the time, as much as possible at every 
opportunity, so I had some expectations. But the errors I’m 
getting don’t fit in with the previous understanding I had with 
the familiar ‘const’ keyword and make me think there must be 
something else going on. So I will need to capture an example in 
the wild, cage it and bring it in for scientific examination.


I can’t ask for an explanation of things going on that you can’t 
inspect for yourself, obviously. And I don’t understand what the 
problem is with using in as much as possible yet having to remove 
it sometimes when something immutable is in use.


Re: Code duplication where you wish to have a routine called with either immutable or mutable arguments

2023-05-30 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 31 May 2023 at 03:23:01 UTC, Cecil Ward wrote:

On Tuesday, 30 May 2023 at 04:15:22 UTC, Ali Çehreli wrote:

On 5/29/23 19:57, Cecil Ward wrote:

> I wish to have one routine
> that can be called with either immutable or (possibly)
mutable argument
> values.

'const' should take both immutable and mutable. Can you show 
your case with a short example?


> Could I make the one routine into a template?

That could work but give 'in' parameters a try:

  https://dlang.org/spec/function.html#in-params

Ali


T2 foo( in T1 x ) { return bar( x ) };

It was with something vaguely like the above that I had to 
remove the in (templatised generic function possibly) in order 
to get it to compile with GDC or LDC on godbolt.org (or 
d.godbolt.org) latest versions available. -O3 
-release/-frelease -march=native/-mcpu-native


I have to admit that I don’t really understand immutable. I have 
an idea that it could mean that an object has an address in ROM, 
so its value will never change. Maybe const doesn’t give you such 
a strong guarantee, disallows ‘you’ from modifying it but others 
might do so, but who knows. Without a guarantee as strong as the 
first idea I can’t really understand how const can work properly. 
"You treat it as const so do not modify it, but it might not be 
eternally fixed and  unchanging" that doesn’t seem to have enough 
value to me. But maybe I’ve got the whole thing wrong.


In an architecture where you have strongly typed (tagged ? 
segmented?) different kinds of addresses, I can see why you might 
be getting type mismatch errors when passing addresses around.


Re: Code duplication where you wish to have a routine called with either immutable or mutable arguments

2023-05-30 Thread Cecil Ward via Digitalmars-d-learn

On Tuesday, 30 May 2023 at 04:15:22 UTC, Ali Çehreli wrote:

On 5/29/23 19:57, Cecil Ward wrote:

> I wish to have one routine
> that can be called with either immutable or (possibly)
mutable argument
> values.

'const' should take both immutable and mutable. Can you show 
your case with a short example?


> Could I make the one routine into a template?

That could work but give 'in' parameters a try:

  https://dlang.org/spec/function.html#in-params

Ali


T2 foo( in T1 x ) { return bar( x ) };

It was with something vaguely like the above that I had to remove 
the in (templatised generic function possibly) in order to get it 
to compile with GDC or LDC on godbolt.org (or d.godbolt.org) 
latest versions available. -O3 -release/-frelease 
-march=native/-mcpu-native





Code duplication where you wish to have a routine called with either immutable or mutable arguments

2023-05-29 Thread Cecil Ward via Digitalmars-d-learn
I have often come into difficulties where I wish to have one 
routine that can be called with either immutable or (possibly) 
mutable argument values. The argument(s) in question are in, 
readonly, passed by value or passed by const reference. Anyway, 
no one is trying to write to the items passed in as args, no 
badness attempted.


When I call the routine from one place with an argument that is 
immutable and then from another that is not, or it could be const 
as well, or not, that’s when I get all kinds of type mismatch 
errors. And I certainly don’t want to pour cast-like type 
conversion operations over all the place at these problem 
occurrences. it’s surely asking for problems.


Could I make the one routine into a template? Even if I did, that 
would perhaps create additionally problems, since even if it all 
worked and instantiated either immutable or mutable forms of the 
routine, what happens if I have two args and they have a mixture 
of immutable and no immutable args ? So nargs * 2 ( or more) 
possibilities?


I’m out of my depth here.


Re: quick question, probably of little importance...

2023-04-30 Thread Cecil Ward via Digitalmars-d-learn

On Monday, 1 May 2023 at 03:53:24 UTC, Cecil Ward wrote:

On Wednesday, 26 April 2023 at 23:07:39 UTC, WhatMeWorry wrote:

[...]




Correction: I can’t count. There are only two instructions in 
parallel with another pair running alongside, not three. The 
first reg, reg move counts as zero cycles, so the total time is 
just the sum of the following three instructions’ times, ignoring 
the other parallel stream.


Re: quick question, probably of little importance...

2023-04-30 Thread Cecil Ward via Digitalmars-d-learn

On Wednesday, 26 April 2023 at 23:07:39 UTC, WhatMeWorry wrote:
On Wednesday, 26 April 2023 at 23:02:07 UTC, Richard (Rikki) 
Andrew Cattermole wrote:

Don't forget ``num % 2 == 0``.

None should matter, pretty much all production compilers 
within the last 30 years should recognize all forms of this 
and do the right thing.


Thanks. Fastest reply ever! And I believe across the world?   I 
suppose my examples required overhead of a function call. So 
maybe num % 2 == 0 is fastest?


I made a small change, making the retval a bool rather than an 
int. I got slightly better code generation with the int, as it 
seems that some of the compilers have not yet got all the good 
tricks they should be using when manipulating bool-typed 
expressions and also it can be one extra instruction converting 
values to bool strictly zero or one, not zero or any non-zero 
value. Here’s the D, enlarged a little so that we can see your 
routine in action, inlined. Your isEven boils down to two 
instructions with a seriously optimising compiler. I’ve included 
the x86-64 machine code generated by the GDC and LDC compilers so 
you can see how fast it is. GDC made a bit of a dog’s breakfast 
of my longer routine whereas LDC performed superbly. GDC 
generated twice as much code, but its excellent instruction 
scheduler and what looks like an awareness of ILP mean that the 
two streams of instructions will be carried out in parallel  so 
the two streams will only take three instruction times - ie 
whatever the total time is for those three instruction in the one 
stream - not six.


bool isEven( int num )
{
return ! ( num & 1 );
}

bool AreBothEven( int a, int b )  // returns true if both 
arguments are even

{
return isEven( a )  &&  isEven( b );
}

===
Compiler output:: GDC:: x86-64: -O3 -mcpu=native -frelease

bool isEven( int ):
mov eax, edi
not eax
and eax, 1
ret

bool AreBothEven( int, int ):
mov eax, edi
not esi
not eax
and esi, 1
and eax, 1
cmovne  eax, esi
ret

===
Compiler LDC: x86-64: -O3 -mcpu=native -release

bool isEven( int ):
testdil, 1
seteal
ret

bool AreBothEven( int, int ):
or  edi, esi
testdil, 1
seteal
ret


Re: std.socket tutorials? examples?

2023-04-30 Thread Cecil Ward via Digitalmars-d-learn

On Sunday, 30 April 2023 at 22:37:48 UTC, Adam D Ruppe wrote:

On Sunday, 30 April 2023 at 22:10:31 UTC, Cecil Ward wrote:
How do we wait for an ‘or’ of multiple asynchronous events in 
this kind of code?


You can set a timeout value for Socket.select, but Phobos isn't 
going to help you with anything other than sockets and timeouts 
(despite the fact the underlying operating systems can, in 
fact, do it).


There's a few other libs that can help with this, including one 
I'm aiming to release some time in May, or vibe.d has its own 
ways of doing it, among others. You can also import 
core.sys.stuff and call the OS functions without a middle man.


But the D stdlib is quite underpowered when it comes to these 
things. Socket.select is ok but just the basics.


Many thanks, Adam.


Re: std.socket tutorials? examples?

2023-04-30 Thread Cecil Ward via Digitalmars-d-learn

On Saturday, 29 April 2023 at 11:26:20 UTC, Adam D Ruppe wrote:

On Saturday, 29 April 2023 at 10:56:46 UTC, Jan Allersma wrote:

auto clientResult = Socket.select(clientSet, null, null);



There's probably nothing in clientSet, so it is waiting for 
nothing you almost always want to have just one call to 
select in the program, not two, the whole point is to combine 
checks.


I wrote a thing you might want to read too:

http://dpldocs.info/this-week-in-d/Blog.Posted_2019_11_11.html#sockets-tutorial


How do we wait for an ‘or’ of multiple asynchronous events in 
this kind of code? In WinNT iirc there is a very nice o/s 
function that can wait on various kinds of asynch i/o, waiting on 
operations of different types if I’ve understood it correctly. 
The kind of thing I might want to do is wait on an or of IP 
packets arriving, send-completion of IP packets, timers 
completing, IPC messages coming in, key presses or event mouse 
events and the order in which these events arrive is of course 
not predictable. I might want a key press event to break out of 
something or to control an application. Everyone wants timer 
events for timeouts.


Writing a dejargoniser - producing read ke analysis output in English that explains GDC / LDC asm code’s parameters and clobbers

2023-04-05 Thread Cecil Ward via Digitalmars-d-learn
How much code do you thing I would need to write for this? I’m 
still thinking about its feasibility. I don’t want to invent the 
wheel and write a custom parser by hand, so’d rather steal the 
code using sim eg called ‘a library’. :-)


The idea would be that the user could run this to sanity-check 
her understanding of the sometimes arcane GDC asm code 
outputs/inputs/clobbers syntax, and see what her asm code’s 
constraints are actually going to do rather than what she thinks 
it’s going to do. Clearly I can’t readily start parsing the asm 
body itself, I would just inspect the meta info. (If that’s the 
right word?)


I would have a huge problem with LDC’s alternative syntax unless 
I could think of some way to pre-transform and munge it into GDC 
format.


I do wish LDC (and DMD) would now converge on the GDC asm syntax. 
Do you think that’s reasonably doable?


Re: enum and const or immutable ‘variable’ whose value is known at compile time

2020-10-02 Thread Cecil Ward via Digitalmars-d-learn

On Thursday, 17 September 2020 at 01:57:39 UTC, Mike Parker wrote:

On Thursday, 17 September 2020 at 00:32:40 UTC, Cecil Ward


So can the result of declaring certain things with enum ever 
have an _address_ then? (According to legit D code that is, 
never mind the underlying implementation details, which may 
not be observable)


No. Think of it as a named literal.

Thank you Mike. That’s exactly what I thought. And it’s another 
reason in favour of using enum - that it forbids address-taking 
and so declares that there will be none.


Re: enum and const or immutable ‘variable’ whose value is known at compile time

2020-09-16 Thread Cecil Ward via Digitalmars-d-learn
On Wednesday, 16 September 2020 at 17:19:13 UTC, Adam D. Ruppe 
wrote:
On Wednesday, 16 September 2020 at 17:12:47 UTC, Cecil Ward 
wrote:

then is there any downside to just using enum all the time?


For a non-string array, enum may give runtime allocations that 
static immutable won't.


Generally think of enum as being replaced with the literal 
representation and array literals actually make a new array.


This may or may not matter to you.


So can the result of declaring certain things with enum ever have 
an _address_ then? (According to legit D code that is, never mind 
the underlying implementation details, which may not be 
observable)


I actually really hate the way enum was bent out of shape 
and twisted from its original purpose so that finally we end up 
with a way of defining only one value, not the whole range of 
permissible values for a type as in the beginning.


I wish there were just a keyword ‘constant’ or something (yes, I 
know, you could just call that something ‘enum’, or 
‘const’)


enum and const or immutable ‘variable’ whose value is known at compile time

2020-09-16 Thread Cecil Ward via Digitalmars-d-learn

A really stupid question, I fear.

If I have some kind of declaration of some ‘variable’ whose value 
is strictly known at compile time and I do one of the following 
(rough syntax)


either
   enum foo = bar;
or
   const foo = bar;
or
   immutable foo = bar;

then is there any downside to just using enum all the time?

- I don’t need to take the address of foo, in fact want to 
discourage , (as I said, given that I can do so)


Is there any upside either to using enum?

I’m a bit nervous about using immutable having had bad allergic 
reactions when passing immutable ‘variables’ to functions and so 
just tend to use const or enum.


  1   2   >