Re: How can I tell D that function args are @nogc etc.

2024-04-11 Thread John Dougan via Digitalmars-d-learn
On Thursday, 11 April 2024 at 15:00:49 UTC, Steven Schveighoffer 
wrote:


So D can provide a nice mechanism to show what is happening -- 
`pragma(msg, ...)`


If I do that with the two types above I see something *very* 
interesting:


```d
pragma(msg, FnPrefixT);
pragma(msg, FnSuffixT);
```

```
bool function(int) nothrow @nogc
bool function(int) nothrow @nogc @safe
```

That surprises me. `nothrow` and `@nogc` go onto the type, but 
not `@safe` if put before the declaration? I have no idea why. 
All I can think of is that it is a bug.




`pragma(msg,...)` is very useful. Thanks.

My general impressions were correct then. It shouldn't matter on 
which side the attrs get put, except in some ambiguous cases. 
It's just broken. Not every day you get to blame a compiler bug.


Feeding:
```d
alias FnPrefixT = @safe nothrow @nogc bool function(int);
alias FnSuffixT = bool function(int) @safe nothrow @nogc ;

pragma(msg, FnPrefixT);
pragma(msg, FnSuffixT);

void main() { return; }
```

into run.dlang and having it compile with all the 
compilers...gets the same result all the way back to 2.060. It 
has this issue with gdc 2.076, which is what I'm using normally.


What is the procedure for bug reporting? I'm looking at the 
issues tracker and have no clue how to drive the search to see if 
this is already there.




-Steve


-- john



Re: "Error: `TypeInfo` cannot be used with -betterC" on a CTFE function

2024-04-11 Thread Liam McGillivray via Digitalmars-d-learn
On Tuesday, 9 April 2024 at 12:45:55 UTC, Richard (Rikki) Andrew 
Cattermole wrote:


On 09/04/2024 12:48 PM, Liam McGillivray wrote:

I suppose this was a good new thing to learn, though I'm still 
quite far from being able to construct a function from another 
function using a template.


I suppose that if I wanted it to make a function from another 
function, I may be able to do it in a template using some 
`static foreach` to make arrays of function parameters, and 
then combine them together without the use of strings, instead 
using placeholders (aliases or whatever they'd be called) and 
maybe the `tupleof` function. Am I headed in the right 
direction (if you can understand my weak attempt to describe 
the direction I'm thinking of going in)?


``tupleof`` isn't a function, its a property to get a "tuple" a 
sequence of fields for a struct/class.


However most likely you'd have to resort to string mixins if 
you're messing about with parameters like I think? you are 
asking for.


I'm not entirely sure what you're wanting there.


Here's what I wanted to do.

In the library I'm working on, there are various declarations for 
functions defined in an external C library following the line 
`extern (C) @nogc nothrow:`. Here are some examples of such 
declarations which have a `const(char)*` parameter:

```
void InitWindow(int width, int height, const(char)* title);
void SetWindowTitle(const(char)* title);
Shader LoadShader(const(char)* vsFileName, const(char)* 
fsFileName);

```

I wanted to generate definitions of overloads of these functions 
using strings as parameters instead of `const(char)*`. For the 
`InitWindow` function shown above, the overload should be defined 
like this:

```
void InitWindow(int width, int height, ref string title) {
InitWindow(width, height, cast(const(char)*)title);
}
```
or alternatively, like the following:
```
void InitWindow(int width, int height, string title) {
InitWindow(width, height, title.toStringz);
}
```

I'm not sure which of these is better, thought the latter one 
would need to be modified to not accept string literals. I found 
that the former one has the advantage that making the `title` 
parameter `ref string` means that string literals use the 
existing version of the function. I know that the former can be 
`@nogc`, unlike the latter, though I don't know if there is any 
advantage offered by `toStringz` over `cast(const(char)*)`.


But anyway, my goal was to generate function overloads like 
either of the above. I have already posted a version of a CTFE 
function that does this, though I put them under `version 
(D_TypeInfo)` so that they aren't available in `betterC` builds, 
since the function I wrote doesn't build with `betterC`.


Re: mmap file performance

2024-04-11 Thread Andy Valencia via Digitalmars-d-learn
On Thursday, 11 April 2024 at 14:54:36 UTC, Steven Schveighoffer 
wrote:
For a repeatable comparison, you should provide the code which 
does 1MB reads.


With pleasure:

import std.stdio : writeln, File, stderr;

const uint BUFSIZE = 1024*1024;

private uint
countnl(File f)
{
uint res = 0;
char[BUFSIZE] buf;

while (!f.eof) {
auto sl = f.rawRead(buf);
foreach (c; sl) {
if (c == '\n') {
res += 1;
}
}
}
return res;
}

private uint
procfile(in string fn) {
import std.exception : ErrnoException;
File f;

try {
f = File(fn, "r");
} catch(ErrnoException e) {
stderr.writeln("Can't open: ", fn);
return 0;
}
uint res = countnl(f);
f.close();
return res;
}

void
main(in string[] argv)
{
foreach (fn; argv[1 .. $]) {
uint res;
res = procfile(fn);
writeln(fn, ": ", res);
}
}



Re: How can I tell D that function args are @nogc etc.

2024-04-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On Thursday, 11 April 2024 at 03:17:36 UTC, John Dougan wrote:

Interesting. Thank you to both of you.

On Wednesday, 10 April 2024 at 17:38:21 UTC, Steven 
Schveighoffer wrote:
On Wednesday, 10 April 2024 at 11:34:06 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
Place your attributes on the right hand side of the function, 
not the left side.


Use the left side for attributes/type qualifiers that go on 
the return type.


Just a word of warning, this explanation suggests putting 
qualifiers on the left side would affect the return type, this 
is not the case.


So in my example, what did I actually tell the compiler with 
the placement of the attributes? And how was it different 
between the function type alias declaration, and the actual 
function declaration?


More specifically, what are the semantic differences below?
```d
alias FnPrefixT = @nogc nothrow @safe bool function(int);
// Versus
alias FnSuffixT = bool function(int) @nogc nothrow @safe;
```


So D can provide a nice mechanism to show what is happening -- 
`pragma(msg, ...)`


If I do that with the two types above I see something *very* 
interesting:


```d
pragma(msg, FnPrefixT);
pragma(msg, FnSuffixT);
```

```
bool function(int) nothrow @nogc
bool function(int) nothrow @nogc @safe
```

That surprises me. `nothrow` and `@nogc` go onto the type, but 
not `@safe` if put before the declaration? I have no idea why. 
All I can think of is that it is a bug.




and
```d
@nogc nothrow @safe bool fnPrefix(int) { stuff }
// Versus
bool fnSuffix(int) @nogc nothrow @safe  { stuff }
```


```d
pragma(msg, typeof(fnPrefix));
pragma(msg, typeof(fnSuffix));
```

```
nothrow @nogc @safe bool(int)
nothrow @nogc @safe bool(int)
```

(as expected)

-Steve


Re: mmap file performance

2024-04-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On Thursday, 11 April 2024 at 00:24:44 UTC, Andy Valencia wrote:
I wrote a "count newlines" based on mapped files.  It used 
about twice the CPU of the version which just read 1 meg at a 
time.  I thought something was amiss (needless slice 
indirection or something), so I wrote the code in C.  It had 
the same CPU usage as the D version.  So...mapped files, not so 
much.  Not D's fault.  And writing it in C made me realize how 
much easier it is to code in D!


For a repeatable comparison, you should provide the code which 
does 1MB reads.


I have found that mmapped files are faster than reading buffered 
files, but maybe only for large files?


-Steve