Re: mmap file performance

2024-04-17 Thread kdevel via Digitalmars-d-learn

On Thursday, 11 April 2024 at 16:23:44 UTC, Andy Valencia wrote:

[...]
void
main(in string[] argv)

   ^^

What if you want to use

   bool memorymapped;
   getopt (argv, "m", );

inside main? [1]

Have you tried using "rm" [2] instead of "r" as stdioOpenmode 
under Linux

for a "no code" method of employing mmap for reading?

[1] const main args? [2011]
https://forum.dlang.org/post/mailman.2277.1313189911.14074.digitalmars-d-le...@puremagic.com

[2] section "NOTES" in fopen(3)
https://man7.org/linux/man-pages/man3/fopen.3.html


Re: Why is this code slow?

2024-03-24 Thread kdevel via Digitalmars-d-learn

On Sunday, 24 March 2024 at 19:31:19 UTC, Csaba wrote:
I know that benchmarks are always controversial and depend on a 
lot of factors. So far, I read that D performs very well in 
benchmarks, as well, if not better, as C.


I wrote a little program that approximates PI using the Leibniz 
formula. I implemented the same thing in C, D and Python, all 
of them execute 1,000,000 iterations 20 times and display the 
average time elapsed.


Here are the results:

C: 0.04s
Python: 0.33s
D: 0.73s

What the hell? D slower than Python? This cannot be real. I am 
sure I am making a mistake here. I'm sharing all 3 programs 
here:


C: https://pastebin.com/s7e2HFyL
D: https://pastebin.com/fuURdupc
Python: https://pastebin.com/zcXAkSEf


Usually you do not translate mathematical expressions directly 
into code:


```
   n += pow(-1.0, i - 1.0) / (i * 2.0 - 1.0);
```

The term containing the `pow` invocation computes the alternating 
sequence -1, 1, -1, ..., which can be replaced by e.g.


```
   immutable int [2] sign = [-1, 1];
   n += sign [i & 1] / (i * 2.0 - 1.0);
```

This saves the expensive call to the pow function.


How use SafeRefCounted in @safe code safely?

2024-03-23 Thread kdevel via Digitalmars-d-learn

```d
@safe:

void foo ()
{
   import std.typecons : SafeRefCounted;
   SafeRefCounted!int s;
}

unittest {
   import std.exception : assertNotThrown;
   assertNotThrown (foo);
}
```

```
$ dmd -unittest -main -run  sr.d
sr.d(6): Error: `@safe` function `sr.foo` cannot call `@system` 
destructor `std.typecons.SafeRefCounted!(int, 
RefCountedAutoInitialize.yes).SafeRefCounted.~this`
[...]linux/bin64/../../src/phobos/std/typecons.d(7399):
`std.typecons.SafeRefCounted!(int, 
RefCountedAutoInitialize.yes).SafeRefCounted.~this` is declared 
here


```

Inspired by [1] I tried to compile with `-dip1000` 
(`-preview=dip1000`):


```
dmd -dip1000 -unittest -main -run sr.d
1 modules passed unittests
```

So in order to use a phobos template in the `@safe`-dialect of D 
I must enable the DIP1000-mode of the compiler? But what is the 
status of DIP1000? According to [2]'s boilerplate its status is 
"Superseded". Unfortunately it does not mention by what DIP1000 
is superseded.


My question is this: I need RAII for non-memory resources and I 
would like to implement this using SafeRefCounted. Assume all 
this is used in a function deployed into cars for autonomous 
driving. Support for this software must be available for the next 
20 years. Is @safe + SafeRefCounted + -dip1000 future-proof?


[1] Issue 13983 - RefCounted needs to be @safe/Comment 9
https://issues.dlang.org/show_bug.cgi?id=13983#c9

[2] Scoped Pointers

https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1000.md




Re: chain of exceptions, next method

2024-03-06 Thread kdevel via Digitalmars-d-learn
On Saturday, 10 September 2022 at 08:48:39 UTC, Andrej Mitrovic 
wrote:

[...]
I wish the compiler would rewrite scope(failure) to use chained 
exceptions. Otherwise any exceptions thrown within 
scope(failure) can end up losing information about what was the 
original exception that was thrown.


Ran into this issue with the following ordering bug:

   auto tmpfilename = fn.dup ~ ".XX\0";
   int fd = mkstemp (tmpfilename.ptr);
   scope (failure) remove (tmpfilename); // bug:
   if (fd == -1)
  throw new Exception (strerror(errno).to!string);

The error thrown was

   Failed to remove file ...

Is there any work in progress to chain the exceptions in 
scope(failure)?


DIP 1036e not on the DIPs list?

2024-02-23 Thread kdevel via Digitalmars-d-learn

The DIP 1036e is not listed in

   https://github.com/dlang/DIPs/tree/master/DIPs

is this intentional?


Searching for i" in the forum

2024-02-23 Thread kdevel via Digitalmars-d-learn

How do I search for

   i"

in the forum? I get the following errors:

   i" -> Error: malformed MATCH expression: [i"] (1)
   i\" -> Error: malformed MATCH expression: [i\"] (1)
   'i"' -> Error: malformed MATCH expression: ['i"'] (1)
   `i"` -> Error: malformed MATCH expression: [`i"`] (1)
   "i\"" -> Error: malformed MATCH expression: ["i\""] (1)


Re: length's type.

2024-02-08 Thread kdevel via Digitalmars-d-learn

On Thursday, 8 February 2024 at 16:54:36 UTC, Kevin Bailey wrote:

[...]
On Thursday, 8 February 2024 at 15:26:16 UTC, kdevel wrote:


Elegant and correct is this version:

```d
import std.stdio;

int main()
{
char[] something = ['a', 'b', 'c'];

writeln("len: ", something.length);
writeln("typeid(something.length): ",
typeid(something.length));

writeln ("i: -1");
foreach (i, _; something)
writeln("i: ", i);
return 0;
}
```

But it is still a bit too "clever" in the `foreach` statement 
due to the unused variable `_`.


It has a bigger problem. What happens when I change the code in 
the loop but forget to change the code outside the loop?


How exactly is that pseudo index `-1` related to the real indices 
of the array `something`? This is absolutely not clear to me. I 
simply don't see what problem you are trying to solve.


Re: length's type.

2024-02-08 Thread kdevel via Digitalmars-d-learn

On Thursday, 8 February 2024 at 15:00:54 UTC, Kevin Bailey wrote:
By all means, please share with us how you would have written 
that just as elegantly but "correct".


Elegant and correct is this version:

```d
import std.stdio;

int main()
{
char[] something = ['a', 'b', 'c'];

writeln("len: ", something.length);
writeln("typeid(something.length): ",
typeid(something.length));

writeln ("i: -1");
foreach (i, _; something)
writeln("i: ", i);
return 0;
}
```

But it is still a bit too "clever" in the `foreach` statement due 
to the unused variable `_`.


Re: template/mixin magic for to! auto inferring type from variable

2024-02-03 Thread kdevel via Digitalmars-d-learn

On Saturday, 3 February 2024 at 02:20:13 UTC, Paul Backus wrote:

On Friday, 2 February 2024 at 23:25:37 UTC, Chris Katko wrote:
The auto solution won't work for a struct however which I'm 
using:


```D
struct procTable{ //contains all the fields inside a file I'm 
parsing

   uint time;
   int priority;
   string name;
   // etc
   }
```


Maybe you can use `typeof` in that case?

```d
procTable pt;
pt.time = to!(typeof(pt.time))(data[1]);
// etc
```

...although I guess then you're repeating the field name, which 
isn't great either.


```d
struct ProcTable2 {
   uint time;
   int priority;
   string name;

   this (string [this.tupleof.length] initializers)
   {
  import std.conv;
  static foreach (i, field; this.tupleof)
 field = initializers [i].to!(typeof (field));
   }
}

unittest {
   string [3] initializers = ["100", "-5", "foobar"];
   auto pt2 = ProcTable2 (initializers);
   with (pt2) {
  assert(time == 100);
  assert(priority == -5);
  assert(name == "foobar");
   }
}
```


Re: FileException when calling getTimes on a DirEntry

2023-12-26 Thread kdevel via Digitalmars-d-learn

On Tuesday, 26 December 2023 at 21:09:05 UTC, Renato wrote:

On Sunday, 24 December 2023 at 21:18:44 UTC, kdevel wrote:
[...]
I would have expected you asking questions like "Which program 
might have generated that symlink?", "How do I get the 
meta-data from the
symlink and not from the file it points to ?" or "How do I 
handle that exception?".


Who do you think you are to tell me how I should ask questions?


In this thread I didn't tell you how you should ask questions. 
However, if there are any further questions regarding the topic 
of this thread don't hesitate to ask.


Re: FileException when calling getTimes on a DirEntry

2023-12-24 Thread kdevel via Digitalmars-d-learn

On Sunday, 24 December 2023 at 20:00:15 UTC, Renato wrote:
I asked what could be causing an Exception in my code to happen 
as that was quite unexpected.


As I already wrote: Your code tries to fetch the meta-data for an 
object that does not exist.



[..]
Have you ever seen a symlink like the one I'd posted?

```
.#hi.txt -> renato@renato.902129:1701726658
```


It depends on what counts as "like". If I ask google for an 
explanation of your observation, e.g. by asking


hidden dangling symlink with username at sign

it leads me more or less directly to

https://github.com/roxiness/routify/issues/258

"Emacs by default uses dangling symbolic links to guard 
against

accidentally editing the same file from two editors"

Know your tools!


Does that look like your regular symlink?


The name is a valid filename and so is the value. What makes this 
symlink irregular? That it is a dangling symlink?


I don't think it does... that's what I was actually trying to 
find out and hoped others here would've seen this weird 
behaviour before.


I would have expected you asking questions like "Which program 
might have generated that symlink?", "How do I get the meta-data 
from the
symlink and not from the file it points to ?" or "How do I handle 
that exception?".


Re: FileException when calling getTimes on a DirEntry

2023-12-24 Thread kdevel via Digitalmars-d-learn

On Sunday, 24 December 2023 at 14:19:18 UTC, Renato wrote:
I was trying to use a library (fswatch) for watching the file 
system


Watching for what?


[...]
My code is really basic, when the directory modified timestamp 
changes, I list the directory entries with `dirEntries` and 
then call `dirEntry.getTimes()` on it.


The right way to implement a function which watches for changes 
IN the directory is to use an appropriate notification API, e.g. 
inotify [1]. No one wants software running  on their computer 
which runs in a loop and polls the file system endlessly though 
there is no actual work to do.



```d
[...]
entry.getTimes(ac, st);
```


You know what symlinks [2] are? You want the timestamps of the 
symlink and not that of the pointed-to file. In C you would use 
`lstat` instead of `stat` for that purpose.


Sometimes symlinks are used to link to objects which are not 
located in the filesystem [3]. Trying to use getTimes on such 
object throws an exception.


[1] https://man7.org/linux/man-pages/man7/inotify.7.html
[2] https://man7.org/linux/man-pages/man7/symlink.7.html
[3] e.g. `ls -laF /proc/self/ns` in Linux.


Re: now I need -allinst when dmd compiles the unittest

2023-12-16 Thread kdevel via Digitalmars-d-learn
On Tuesday, 5 December 2023 at 03:36:04 UTC, Steven Schveighoffer 
wrote:

Are you using -checkaction=context?


Right.


[...]
For reference:

https://issues.dlang.org/show_bug.cgi?id=22374
https://issues.dlang.org/show_bug.cgi?id=22902
https://issues.dlang.org/show_bug.cgi?id=19937

You even reported one of these...


Thanks for reminding me of these unfixed errors. Wouldn't it be 
advisable to automatically invoke -allinst whenever 
-checkaction=context is encountered?


Re: Changing behavior of associative array

2023-12-16 Thread kdevel via Digitalmars-d-learn

On Saturday, 16 December 2023 at 20:04:54 UTC, Kevin Bailey wrote:
I've added a TON of writeln's to confirm this. The *instant* I 
made the parameter "ref", the real program starts acting as 
expected, and the print-outs show the correct results.


If you comment out this line

```
//m[f] = 1;
```

in your main function of your posted code you can catch up with 
your

real programm insofar as you now need a ref parameter here, too.



Does anyone know why the behavior would change? Has anyone seen 
anything like this?


Sure.



now I need -allinst when dmd compiles the unittest

2023-12-01 Thread kdevel via Digitalmars-d-learn
If I not use -allinst the linker complains when using the current 
msgpack-d v1.0.5, e.g.


[...]msgpack-d/src/msgpack/package.d:203: undefined reference to 
`pure nothrow @nogc @safe immutable(char)[] 
core.internal.dassert._d_assert_fail!(int)._d_assert_fail!(int)._d_assert_fail(scope const(immutable(char)[]), scope ref const(int), scope ref const(int))'


[...]msgpack-d/src/msgpack/packer.d:1326: undefined reference to 
`pure nothrow @nogc @safe immutable(char)[] 
core.internal.dassert._d_assert_fail!(const(int))._d_assert_fail!(int)._d_assert_fail(scope const(immutable(char)[]), scope ref const(int), scope const(int))'


[...]/msgpack-d/src/msgpack/unpacker.d:1505: undefined reference 
to `pure nothrow @nogc @safe immutable(char)[] 
core.internal.dassert._d_assert_fail!(int)._d_assert_fail!(int)._d_assert_fail(scope const(immutable(char)[]), scope ref const(int), scope ref const(int))'




"using `in ref` is deprecated" in client code while the module's unittest does not warn

2023-12-01 Thread kdevel via Digitalmars-d-learn
After switching to dmd v2.105.3 I get this warnings almost 
everywhere. Do I really have to fork msgpack-d in order to get 
rid of these warnings?


Now I replaced every "in ref" with "in" in my own code but I do 
not add that preview flag to the compiler invocation. Is that 
safe?


Re: struct initializer

2023-12-01 Thread kdevel via Digitalmars-d-learn

On Wednesday, 29 November 2023 at 16:48:09 UTC, Paul Backus wrote:

[...]
If you're using a new enough compiler, it even supports named
arguments:

S3 fun2() { return S3(b: 2, a: 5); }


Indeed. Seems to be in dmd since 2.103.0 (2.102.2 didn't support 
this syntax). Alas, the Change Log [1] remain silent about it.


```
commit 42609ae98e0f72a8d2154da50865bc5182c4b6b3
Author: Dennis https://dlang.org/changelog/2.103.0.html


Re: D: Convert/parse uint integer to string. (@nogc)

2023-11-30 Thread kdevel via Digitalmars-d-learn

On Tuesday, 28 November 2023 at 09:43:47 UTC, Dom DiSc wrote:

On Tuesday, 28 November 2023 at 08:51:21 UTC, Mark Davies wrote:

On Friday, 24 November 2023 at 09:35:00 UTC, BoQsc wrote:
```
import std.stdio;

char[10] longToString(long n) @nogc
```


For a 'long' 10 characters is likely to be not enough (long max 
is 9223372036854775808 [...]


`long.max` is 9223372036854775807, `long.min` is 
-9223372036854775808. Besides from the too short buffer the 
`longToString` function neither converts 0 (zero) nor `long.min` 
correctly.





Re: D: Convert/parse uint integer to string. (@nogc)

2023-11-30 Thread kdevel via Digitalmars-d-learn
On Friday, 24 November 2023 at 13:05:30 UTC, Ferhat Kurtulmuş 
wrote:

[...]
```
import core.stdc.stdio : sprintf;
import core.stdc.math : log10;

import std.exception : assumeUnique;
import std.stdio : writeln;

size_t nod(int num){
  return cast(size_t)((num==0)?1:log10(num)+1);
}

void main()
{
   int myint = 23;

   char[80] str;

   sprintf(str.ptr, "%d", myint);

   string _dstring = str[0..nod(myint)].assumeUnique;

   writeln(_dstring);

}
```


What happend to the indentation? Anyway

```
$ ./inttostr -1

$ ./inttostr -2147483648

```

I like `snprintf`:

```d
import core.stdc.stdio : snprintf;
import std.exception : assumeUnique, enforce;
import std.stdio;
import std.conv;
import core.stdc.locale;
import std.format;

void main (string [] args)
{
   setlocale (LC_NUMERIC, "");
   auto myint = args[1].to!long;
   char[27] str;
   auto n = snprintf(str.ptr, str.sizeof, "%'ld", myint);
   enforce (n < str.sizeof, "buffer too small");
   string _dstring = str[0..n].assumeUnique;
   writeln(_dstring);
}
```

```
$ ./l2s -9223372036854775808
-9.223.372.036.854.775.808
```



Re: D: How do I pipe (|) through three programs using std.process?

2023-11-19 Thread kdevel via Digitalmars-d-learn

On Saturday, 18 November 2023 at 18:09:53 UTC, BoQsc wrote:

Latest iteration on this thread.

Limitations:
* pipes through two programs.
* very verbose, hard to use.



What exactly are you trying to achieve?


```
import std;
import std.process;

version (Windows) { enum Find = "find"; }
version (Posix) { enum Find = "grep"; }

void pipeTo(Pipe p, string nextprogram){
spawnShell(nextprogram, p.readEnd, stdout);
```


If you allow invoking the shell from within your program why 
don't you use one of its facilities, i.e. the shell's pipe 
operator `|`, in the first place? `spawnShell` does not execute 
`nextprogram` but it executes it under the shell.



```
 }

auto program(string name){
Pipe p = std.process.pipe;
spawnShell(name, stdin, p.writeEnd);
return p;
}

void main()
{
program("echo HelloWorld").pipeTo(nextprogram: Find ~ ` 
"HelloWorld"`);


Have I missed the advent of named function arguments in D?


```
}
```


Your whole program shrinks considerably:

```
import std;
import std.process;

version (Windows) { enum Find = "find"; }
version (Posix) { enum Find = "grep"; }
void main()
{
spawnShell("echo HelloWorld | " ~ Find ~ ` 
"HelloWorld"`).wait;

}
```



Re: D: How do I pipe (|) through three programs using std.process?

2023-11-11 Thread kdevel via Digitalmars-d-learn

On Saturday, 11 November 2023 at 17:29:14 UTC, BoQsc wrote:

https://dlang.org/library/std/process.html

How do I pipe (|) through three programs using std.process?

```
echo This is a sample text | find "sample" | find "text"
```


```d
import std.stdio;
import std.process;

version (Windows) { enum Find = "find"; }
version (Posix) { enum Find = "grep"; }

int main (string [] args)
{
   auto p1 = pipe;
   auto p2 = pipe;

   auto pid1 = spawnProcess (args [1..$], stdin, p1.writeEnd);
   auto pid2 = spawnProcess ([Find, "sample"], p1.readEnd, 
p2.writeEnd);

   auto pid3 = spawnProcess ([Find, "text"], p2.readEnd, stdout);
   wait (pid1);
   wait (pid2);
   wait (pid3);
   return 0;
}
```

```
$ ./pip echo This is a sample text
This is a sample text
$ ./pip echo This is an ample text
```


Re: Finding duplicate elements

2023-08-15 Thread kdevel via Digitalmars-d-learn

On Tuesday, 15 August 2023 at 17:59:27 UTC, vino wrote:
 Request your help in finding duplicate element without sorting 
as per the below example


```d
module remove_duplicates;
import std.stdio;
import std.format : format;
import std.string : strip;

int main (string [] args)
{
   bool [string] found;
   string [] result;
   foreach (s; args [1..$]) {
  auto t = s.strip;
  if (t == "")
 continue;
  if (t in found)
 stderr.writefln!"Duplicate element found: <%s>" 
("element name");

  else {
 found [t] = true;
 result ~= t;
  }
   }
   result.writeln;
   return 0;
}
```

```
$ ./remove-duplicates " test3" "test2 " " test1 " " test1 " " "
Duplicate element found: 
["test3", "test2", "test1"]
```


Re: "macro" expansion to build switch case code

2023-07-02 Thread kdevel via Digitalmars-d-learn

On Sunday, 2 July 2023 at 17:02:44 UTC, Paul wrote:
I have a struct similar to the following example.  I'd like to 
build an adder method without having to code the whole method.  
How do I use the D language to do this?  Template, mixins, 
CTFE..all of them?


```d
struct myS {
int a, b, c, d, e, f, g, h, i;
adder(string s, int n) {
final switch (s) {
case "aa" :
a += n; break;
case "bb" :
b += n; break;
   ...
```
Thanks for any assistance.


Thanks for your interesting question!

```
module mys;
import std.exception;

class UnknownRegister : Exception {
   mixin basicExceptionCtors;
}

enum string [] DefaultRegisterSet = [
  "a", "b", "c", "d", "e", "f", "g", "h", "i"
   ];

struct myS {
   int [string] registers;

   this (string [] register_names)
   {
  foreach (r; register_names)
 registers [r] = 0;
   }

   void adder (string s, int n)
   {
  auto p = s in registers;
  enforce!UnknownRegister (p);
  *p += n;
   }

   int opDispatch (string s) ()
   {
  auto p = s in registers;
  enforce!UnknownRegister (p);
  return *p;
   }
}

unittest {
   auto m = myS (DefaultRegisterSet);
   m.adder ("a", 7);
   m.adder ("a", 8);
   assert (m.a == 15);
   assertThrown!UnknownRegister (m.adder ("j", -1));
   assertThrown!UnknownRegister (m.j == 0);
}
```


Re: string to char[4] FourCC conversion

2023-05-27 Thread kdevel via Digitalmars-d-learn
On Friday, 26 May 2023 at 13:18:15 UTC, Steven Schveighoffer 
wrote:

[...]
This worked for me:

```d
char[4] fourC(string s)
{
if(s.length >= 4)
return s[0 .. 4];


Silent truncation? Non-ASCII chars?


char[4] res = 0;


According to [1], [2] or [3] that should read

```
char[4] res = ' ';
```


res[0 .. s.length] = s;
return res;
}
```


[1] Multimedia Programming Interface and Data Specifications 1.0
IBM Corporation and Microsoft Corporation
August 1991, p. 11

https://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf


[2] http://ffmpeg.org/doxygen/trunk/raw_8c_source.html#l00050

[3] https://en.wikipedia.org/wiki/FourCC
"The byte sequence is usually restricted to ASCII printable 
characters, with space characters reserved for padding shorter 
sequences. [...] Some FourCCs however, do contain non-printable 
characters, and are not human-readable without special formatting 
for display; for example, 10bit Y'CbCr 4:2:2 video can have a 
FourCC of ('Y', '3', 10, 10) which ffmpeg displays as rawvideo 
(Y3[10] [10] / 0x0A0A3359), yuv422p10le."




Re: Lockstep iteration in parallel: Error: cannot have parameter of type `void`

2023-05-23 Thread kdevel via Digitalmars-d-learn

On Saturday, 20 May 2023 at 18:27:47 UTC, Ali Çehreli wrote:

[...]
And I've just discovered something.


Me2! The serial version using array indexing

   void vec_op_naive0 (double [] outp, const double [] inp,
  double function (double) fp)
   {
  enforce (inp.length == outp.length);
  auto i = inp.length;
  while (i--)
 outp [i] = fp (inp [i]);
   }

is nearly thrice as fast as the one using lockstep

   void vec_op (double [] outp, const double [] inp,
  double function (double) fp)
   {
  foreach (ref a, b; lockstep (outp, inp))
 a = fp (b);
   }

I wonder if under this circumstances (lack of speed, lack of 
parallelism out-of-the-box) it makes any sense to prefer lockstep 
over

the indexed array access.


Re: Lockstep iteration in parallel: Error: cannot have parameter of type `void`

2023-05-20 Thread kdevel via Digitalmars-d-learn

Thanks for your explications!

On Friday, 19 May 2023 at 21:18:28 UTC, Ali Çehreli wrote:

[...]
- std.range.zip can be used instead but it does not provide 
'ref' access to its elements.


How/why does sort [1] work with zipped arrays?


[...]

The following amap example there may be useful for your case 
but I could not make the types work:


Do you mean using the function pointer does not work?


// Same thing, but explicitly allocate an array
// to return the results in.  The element type
// of the array may be either the exact type
// returned by functions or an implicit conversion
// target.
auto squareRoots = new float[numbers.length];
taskPool.amap!sqrt(numbers, squareRoots);


This even seems to work with a static function pointer:

   int main ()
   {
  import std.stdio;
  import std.math;
  import std.parallelism;

  const double [] a = [1., 2., 3., 4.];
  double [] b = [0., 0., 0., 0.];

  writeln (a);
  writeln (b);

  double function (double) fp = 
  taskPool.amap!fp (a, b);

  writeln (a);
  writeln (b);
  return 0;
   }

Using an automatic variable gives a deprecation warning

   main.amap!(const(double)[], double[]).amap` function requires a
   dual-context, which is deprecated

[1] https://dlang.org/library/std/range/zip.html


Re: request assistance resolving a std.net.curl segmentation fault

2023-05-20 Thread kdevel via Digitalmars-d-learn

On Friday, 19 May 2023 at 23:36:28 UTC, anonymouse wrote:

[...]
The reason I used a while loop was to detect loss of internet 
connection and resume the process once the connection is 
re-established.


What if the internet connection is not re-established within an 
reasonable amount of time? What if the resource is no longer 
available on the server (HTTP eror 404 [1])? If there is an 
interactive user: Wouldn't it be better have the user restart the 
download at his discretion?



What would have been a better approach?


That depends on where you want to use that download function. If 
it is intended to download a full software update of a modern 
e-vehicle I would suggest not to use such an endless loop. I 
would limit the retries to a low single-digit number greater than 
one and of log the event.


[1] The 404 or other errors are not detected by default.

```
curl.set(CurlOption.failonerror, 1);
```

must be set. In case of error an exception is thrown. This 
unfortunately does not contain the required error information. It 
seems that one must supply an error buffer


```
ubyte [] buf;
curl.set (CurlOption.errorbuffer, buf.ptr);
```

to store that result.


Re: request assistance resolving a std.net.curl segmentation fault

2023-05-19 Thread kdevel via Digitalmars-d-learn

On Friday, 19 May 2023 at 11:07:01 UTC, anonymouse wrote:

What am I doing wrong here?
[...]
curl.set(CurlOption.writedata, );


According to [1] this line must read

```
   curl.set(CurlOption.writedata, cast (void *) fp.getFP());
```

[1] https://curl.se/libcurl/c/CURLOPT_WRITEDATA.html



Lockstep iteration in parallel: Error: cannot have parameter of type `void`

2023-05-19 Thread kdevel via Digitalmars-d-learn

```
import std.range;
import std.parallelism;

void vec_op (double [] outp, const double [] inp,
   double function (double) f)
{
   foreach (ref a, b; parallel (lockstep (outp, inp)))
  a = f (b);
}
```

Should this compile? dmd says

```
[...]/src/phobos/std/parallelism.d(4094): Error: cannot have 
parameter of type `void`
[...]/src/phobos/std/parallelism.d(4095): Error: cannot have 
parameter of type `void`
[...]/src/phobos/std/parallelism.d(3619): Error: template 
instance `std.parallelism.ParallelForeach!(Lockstep!(double[], 
const(double)[]))` error instantiating
lspar.d(7):instantiated from here: 
`parallel!(Lockstep!(double[], const(double)[]))`

```


Re: Returning a reference to be manipulated

2023-04-15 Thread kdevel via Digitalmars-d-learn

On Saturday, 15 April 2023 at 15:50:18 UTC, Dennis wrote:

[...]
care about the type / mutability of the pointer.


Returning `i`'s address in a long does not trigger the escape 
detector:


```
long foo (long s, return ref int i)
{
   s = cast (long) 
   return s;
}

auto bar ()
{
   int i;
   long s;
   return foo (s, i);
}
```

dmd compiles this without complaints.



Re: Returning a reference to be manipulated

2023-04-15 Thread kdevel via Digitalmars-d-learn

On Saturday, 15 April 2023 at 14:10:57 UTC, Dennis wrote:

[...]
This adds complexity, just to add some 'intermediate' safety 
between `@system` and `@safe` in a few cases. It's better to 
keep the rules simple and consistent.


Thanks for the answer! While playing around with return ref I 
came across this:


```
string foo (string s, return ref int i)
{
   return s;
}

auto bar ()
{
   int i;
   string s;
   return foo (s, i);
}
```

```
$ dmd rr.d
rr.d(10): Error: returning `foo(s, i)` escapes a reference to 
local variable `i`

```

Does that make sense?


Re: Returning a reference to be manipulated

2023-04-15 Thread kdevel via Digitalmars-d-learn
On Saturday, 15 April 2023 at 13:24:52 UTC, Richard (Rikki) 
Andrew Cattermole wrote:

On 16/04/2023 1:20 AM, kdevel wrote:
On Saturday, 15 April 2023 at 12:45:31 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
It was bad analysis by the compiler, which has since been 
corrected.


It should have been applied only to @safe code.


But why is the @unsafe programmer now left unprotected in 
cases like this


```
ref int foo (ref int i)
//   `--- automatically insert `return` here?
{
    return i;
}
```

where the compiler recognizes that the function returns a ref 
parameter?


Under which circumstances is it a mistake to insert the 
`return` at the indicated position? If there are none why 
can't it be done implicitly (automatically)?


@system (which is currently the default, there is a strong 
desire to change this), does no safety checks.


When I insert `return` before `ref int` and compile the code dmd 
says


```
returnref2.d(9): Error: returning `foo(i)` escapes a reference to 
local variable `i`

```

Isn't this a safety check? (The code does not contain any `@`.)

My question was if it is problematic if dmd inserted a `return` 
before any `ref` parameter a function returns.


Did the removed code which checked for returning ref parameters 
have false positives?


If not again my question: Under what circumstances would it be a 
mistake to insert `return` before the respective `ref` parameter?






Re: Returning a reference to be manipulated

2023-04-15 Thread kdevel via Digitalmars-d-learn
On Saturday, 15 April 2023 at 12:45:31 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
It was bad analysis by the compiler, which has since been 
corrected.


It should have been applied only to @safe code.


But why is the @unsafe programmer now left unprotected in cases 
like this


```
ref int foo (ref int i)
//   `--- automatically insert `return` here?
{
   return i;
}
```

where the compiler recognizes that the function returns a ref 
parameter?


Under which circumstances is it a mistake to insert the `return` 
at the indicated position? If there are none why can't it be done 
implicitly (automatically)?


Re: Returning a reference to be manipulated

2023-04-15 Thread kdevel via Digitalmars-d-learn

On Friday, 14 April 2023 at 11:18:21 UTC, Dennis wrote:

On Friday, 14 April 2023 at 10:31:58 UTC, kdevel wrote:

But in fact it is returned unless it is `return ref`.


When using `return ref`, `return scope`, `scope` etc., you 
should be using the latest compiler and annotate functions you 
want checked with `@safe`.


We are writing at cross puroposes. I am not asking how I could 
help the compiler. My point is: I have code from 2019 which 
produced a deprecation warning


```
returnref2.d(3): Deprecation: returning i escapes a reference to 
parameter i, perhaps annotate with return

```

when compiled with with the compiler of that time (v2.093.1). 
When I use a recent compiler (v2.102.2) the code compiles without 
any complaints. I am asking myself what has deprecacted? I mean: 
Deprecation notes are built into the compiler in order to enable 
a "soft landing" for a scheduled breaking change. But I cannot 
see any breaking change at all regarding the code example in


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



Re: Returning a reference to be manipulated

2023-04-14 Thread kdevel via Digitalmars-d-learn

On Friday, 14 April 2023 at 09:42:14 UTC, Bastiaan Veelo wrote:

[...]
Up to dmd v2.100.2 I am warned/get an error during compilation:

```
$ dmd returnref2.d
returnref2.d(3): Deprecation: returning `i` escapes a 
reference to parameter `i`
returnref2.d(1):perhaps annotate the parameter with 
`return`

$ dmd -dip1000 returnref2.d
returnref2.d(3): Error: returning `i` escapes a reference to 
parameter `i`
returnref2.d(1):perhaps annotate the parameter with 
`return`

```

With later dmd versions (up to including v2.102.2) the code 
compiles without complaints. Is this intended?


I think this is intended. Adding `@safe:` on top makes the 
complaint come back (in dmd  2.102 it is deprecated, in 2.103 
it is an error).


What irritates me is that only with `return ref int`

```
ref int foo (return ref int i)
{
   return i;
}
[...]
```

dmd complains:

```
returnref2.d(9): Error: returning `foo(i)` escapes a reference to 
local variable `i`

```

The documentation [1] says that a `ref` parameter may not be 
returned unless it is `return ref`. But in fact it is returned 
unless it is `return ref`. Probably i get/got the meaning of the 
English modal verb "may" wrong.


The documentation also says that `return ref` parameters are used 
to ensure that the returned reference will not outlive the 
matching argument's lifetime. I don't get it! Is there any 
legitimate use of returning a ref such that it outlives the 
matching argument's lifetime? If not: Isn't this `return ref` 
completely redundant?


[1] https://dlang.org/spec/function.html


Re: Returning a reference to be manipulated

2023-04-13 Thread kdevel via Digitalmars-d-learn

On Thursday, 13 April 2023 at 22:09:48 UTC, Jacob Shtokolov wrote:

[...]
ref opIndex(string key) return
[...]


Regarding the return ref I found this code of 2019 on my harddisk 
which is from or was motivated by a dconf talk:


```
ref int foo (ref int i)
{
   return i;
}

ref int bar ()
{
   int i;
   return foo (i);
}

void main ()
{
   import std.stdio;
   auto i = bar;
   i.writeln;
}
```

Up to dmd v2.100.2 I am warned/get an error during compilation:

```
$ dmd returnref2.d
returnref2.d(3): Deprecation: returning `i` escapes a reference 
to parameter `i`
returnref2.d(1):perhaps annotate the parameter with 
`return`

$ dmd -dip1000 returnref2.d
returnref2.d(3): Error: returning `i` escapes a reference to 
parameter `i`
returnref2.d(1):perhaps annotate the parameter with 
`return`

```

With later dmd versions (up to including v2.102.2) the code 
compiles without complaints. Is this intended?


Re: 'auto' keyword

2023-03-12 Thread kdevel via Digitalmars-d-learn

On Sunday, 12 March 2023 at 13:27:05 UTC, Adam D Ruppe wrote:

[...] *any* storage class will work for type inference. [...]


After heaving read [1] I immediately thought of this:

   void main ()
   {
  deprecated i = 3;
  i = 4;
   }
   $ dmd test.d
   test.d(4): Deprecation: variable `test.main.i` is deprecated

Does that make sense???

[1] https://issues.dlang.org/show_bug.cgi?id=7432
Issue 7432 - DMD allows variables to be declared as pure


Should importC fail on invalid C code?

2023-01-13 Thread kdevel via Digitalmars-d-learn
After reading Walter's remark "ImportC sees those macro 
definitions and transforms them into manifest constant 
declarations" in


Issue 23622 - ImportC #defines conflict with declarations

I wondered how it was implemented:

`myccode.c`
```
int getx ()
{
   return X;
#define X 1
}
```

`imc.d`
```
unittest {
   import myccode;
   assert (false, "Should img.c really compile?");
}
```

```
dmd -O -checkaction=context -unittest -main myccode.c -run imc.d
imc.d(3): [unittest] Should img.c really compile?
1/1 modules FAILED unittests
```


Re: Why does the importC example not compile?

2023-01-13 Thread kdevel via Digitalmars-d-learn

On Friday, 13 January 2023 at 12:20:23 UTC, Dennis wrote:
I don't think there's a way to test examples of separate 
compilation in the spec currently.


What must be added or changed in order to test every example 
which is intended to produce an executable?


Why does the importC example not compile?

2023-01-13 Thread kdevel via Digitalmars-d-learn

https://dlang.org/spec/importc.html

`square.c`
```
int square(int i)
{
   return i * i;
}
```

`demo.d`
```
import std.stdio;
import square;
void main()
{
int i = 7;
writefln("The square of %s is %s", i, square(i));
}
```

```
$ dmd --version
DMD64 D Compiler v2.101.1
Copyright (C) 1999-2022 by The D Language Foundation, All Rights 
Reserved written by Walter Bright

$ dmd demo.d square.c
demo.d(6): Error: function expected before `()`, not `module 
square` of type `void`

```

I would have expected that each and every piece of code in the 
documentation is automatically compiled with any new compiler 
release.


Re: dirEntries removes entire branches of empty directories

2022-11-14 Thread kdevel via Digitalmars-d-learn

On Monday, 14 November 2022 at 21:05:01 UTC, kdevel wrote:

[...]
the runtimes are

   ftw   : 98 ms, 470 ÎŒs, and 2 *beeep*
   dirEntries: 170 ms, 515 ÎŒs, and 2 *beeep*

(to be continued)


When I examine the process with strace it appears that the ftw 
version gets the whole information from readdir alone. The 
dirEntries version seems to call lstat on every file (in order to 
check that it is not a symlink)


Breakpoint 1, 0xf7cc59d4 in lstat64 () from 
[...]gcc-12.1/lib/libgphobos.so.3

(gdb) bt
#0  0xf7cc59d4 in lstat64 () from 
[...]gcc-12.1/lib/libgphobos.so.3
#1  0xf7a5269b in std.file.DirEntry._ensureLStatDone() () from 
[...]gcc-12.1/lib/libgphobos.so.3
#2  0xf7a5276a in std.file.DirEntry.linkAttributes() () from 
[...]gcc-12.1/lib/libgphobos.so.3
#3  0xf7a528c9 in std.file.DirIteratorImpl.mayStepIn() () from 
[...]gcc-12.1/lib/libgphobos.so.3
#4  0xf7a545ae in std.file.DirIteratorImpl() () from 
[...]gcc-12.1/lib/libgphobos.so.3
#5  0xf7a5466e in core.internal.lifetime() () from 
[...]gcc-12.1/lib/libgphobos.so.3
#6  0xf7a546ef in core.internal.lifetime() () from 
[...]gcc-12.1/lib/libgphobos.so.3
#7  0xf7a54726 in core.lifetime() () from 
[...]gcc-12.1/lib/libgphobos.so.3
#8  0xf7a54762 in std.typecons() () from 
[...]gcc-12.1/lib/libgphobos.so.3
#9  0xf7a547d6 in std.typecons() () from 
[...]gcc-12.1/lib/libgphobos.so.3
#10 0xf7a54811 in std.file.DirIterator.__ctor() () from 
[...]gcc-12.1/lib/libgphobos.so.3
#11 0xf7a54882 in std.file.dirEntries() () from 
[...]gcc-12.1/lib/libgphobos.so.3
#12 0x08088e25 in direntrybenchmark.directoryWalk_dirEntries() 
(root=..., dump=false) at direntrybenchmark.d:111


and after that an additional stat on the same file in order to 
check if it is a directory:


Breakpoint 2, 0xf7cc5954 in stat64 () from 
[...]gcc-12.1/lib/libgphobos.so.3

(gdb) bt
#0  0xf7cc5954 in stat64 () from [...]gcc-12.1/lib/libgphobos.so.3
#1  0xf7a527e1 in std.file.DirEntry._ensureStatOrLStatDone() () 
from [...]gcc-12.1/lib/libgphobos.so.3
#2  0xf7a5287a in std.file.DirEntry.isDir() () from 
[...]gcc-12.1/lib/libgphobos.so.3
#3  0x08088e6c in direntrybenchmark.directoryWalk_dirEntries() 
(root=..., dump=) at direntrybenchmark.d:112
#4  0x08089105 in __lambda7 (__capture=0xf7411000) at 
direntrybenchmark.d:158

#5  0x0809f8aa in benchmark (n=1, __capture=)
at 
/md11/sda2-usr2l/gcc-12.1/lib/gcc/x86_64-pc-linux-gnu/12.1.0/include/d/std/datetime/stopwatch.d:421
#6  __foreachbody9 (__capture=0xf7411000, __applyArg0=..., 
__applyArg1=...) at direntrybenchmark.d:162
#7  0xf7c98bd9 in _aaApply2 () from 
[...]gcc-12.1/lib/libgphobos.so.3
#8  0x0808dee1 in direntrybenchmark.main_() (args=...) at 
direntrybenchmark.d:161





Re: dirEntries removes entire branches of empty directories

2022-11-14 Thread kdevel via Digitalmars-d-learn

On Friday, 11 November 2022 at 16:00:12 UTC, Ali Çehreli wrote:

On 11/11/22 05:13, kdevel wrote:

> dmd -O compiled patched (see below!) version applied to
/usr/bin on my
> desktop
> yields:
>
> ftw   : 363 ms, 750 ÎŒs, and 5 [*]
> dirEntries: 18 secs, 831 ms, 738 ÎŒs, and 3 [*]

Great. I did not use -O with my test. It may have to do 
something with the performance of the hard disk.


It has to do with the large number of symlinks. When I use

   dirEntries(root, SpanMode.depth, false)

the runtime is dramatically reduced and with

   entries ~= DirectoryEntry(entry, entry.size);

the runtimes are

   ftw   : 98 ms, 470 ÎŒs, and 2 *beeep*
   dirEntries: 170 ms, 515 ÎŒs, and 2 *beeep*

(to be continued)



Re: dmd 2.099 regression: unittest -checkaction=context and import std.regex cause lots of undefined references

2022-11-14 Thread kdevel via Digitalmars-d-learn

On Monday, 14 November 2022 at 17:08:38 UTC, Gavin Ray wrote:

Just came here to say I hit the same bug, here's my import list:


* https://issues.dlang.org/show_bug.cgi?id=19937
  object._d_assert_fail linker error if compiling with 
-checkaction=context


* https://issues.dlang.org/show_bug.cgi?id=22374
  [REG 2.093] 'import std;' with -checkaction=context causes link 
error


* https://issues.dlang.org/show_bug.cgi?id=22902
  dmd 2.099 regression: unittest -checkaction=context and import 
std.regex causes link error


Does `dmd -allinst ...` help in your case?


Re: dirEntries removes entire branches of empty directories

2022-11-11 Thread kdevel via Digitalmars-d-learn

On Thursday, 10 November 2022 at 21:27:28 UTC, Ali Çehreli wrote:

On 11/9/22 12:06, Ali Çehreli wrote:

> I am using its sibling 'ftw'

Now that we know that dirEntries works properly, I decided not 
to use ftw.


However, ftw performs about twice as fast as dirEntries 
(despite some common code in the implementation below).


dmd -O compiled patched (see below!) version applied to /usr/bin 
on my desktop

yields:

ftw   : 363 ms, 750 ÎŒs, and 5 [*]
dirEntries: 18 secs, 831 ms, 738 ÎŒs, and 3 [*]

(* = offending units removed)


[...]
foreach (entry; dirEntries(root, SpanMode.depth)) {
if (entry.isDir) {
dirs ~= entry;

} else {
entries ~= DirectoryEntry(entry, entry.getSize);
}


strace reports that entry.getSize invokes stat on the file a 
second time. Isn't

the stat buf saved in the entry?

This also gives rise for a complication with symlinks pointing to 
the directory

which contain them:

   $ pwd
   /tmp/k/sub
   $ ln -s . foo
   $ ../direntrybenchmark .
   
std.file.FileException@8[...]/linux/bin64/../../src/phobos/std/file.d(1150): ./foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo: Too many levels of symbolic links

   [...]


[...]
if (args.length != 2) {
stderr.writefln!"Please provide the directory to 
walk:\n\n  %s \n"

(args[0].baseName);
return 1;
}

const dir = buildNormalizedPath("/home/ali/dlang");


diff --git a/direntrybenchmark.d b/direntrybenchmark.d
index 661df51..a9a5616 100644
--- a/direntrybenchmark.d
+++ b/direntrybenchmark.d
@@ -102,8 +102,9 @@ WalkResult directoryWalk_dirEntries(string 
root) {

 if (entry.isDir) {
 dirs ~= entry;

-} else {
-entries ~= DirectoryEntry(entry, entry.getSize);
+}
+else {
+entries ~= DirectoryEntry(entry, 0);
 }
 }

@@ -133,7 +134,7 @@ int main(string[] args) {
 return 1;
 }

-const dir = buildNormalizedPath("/home/ali/dlang");
+const dir = buildNormalizedPath(args[1]);

 auto timings = benchmark!({ directoryWalk_ftw(dir); },
   { directoryWalk_dirEntries(dir); 
})(10);






Re: dirEntries removes entire branches of empty directories

2022-11-09 Thread kdevel via Digitalmars-d-learn

On Wednesday, 9 November 2022 at 19:05:58 UTC, Ali Çehreli wrote:

In case it matters, the file system is ext4.


My code runs in tmp (tmpfs).


2) Make a sub-directory:

  mkdir deleteme/a

Running the program shows no output; 'a' is not visited as a 
directory entry.


Was say strace/ltrace?

```didi.d
import std.stdio;
import std.file;

void main (string [] args)
{
   auto de = dirEntries (args[1], SpanMode.breadth);
   foreach (e; de)
  writeln(e.name);
}
```

```
$ mkdir -p deleteme/a
$ dmd didi
$ ./didi deleteme
deleteme/a


Do you think this is buggy behavior for dirEntries?


Sure.


Re: Generate a pointer to a method of a struct

2022-10-14 Thread kdevel via Digitalmars-d-learn

On Saturday, 15 October 2022 at 00:31:47 UTC, Iain Buclaw wrote:

```
auto funcptr (alias method) ()
{
   return 
}
  :
  fun = funcptr!bar;
  :
```

Which works but neither dmd nor gdc were able to optimize the 
additional function call away.


pragma(inline, true)
auto funcptr (alias method) ()


Thanks. Just found that

```
template funcptr (alias method) {
   enum funcptr = 
}
```

works on both dmd and gdc. This gives rise to questions:

Is this code expected to compile and pass its unittest?

```
struct S {
   void bar () { }
}

enum ei = 
immutable i =   // line 6
const c =   // line 7

unittest {
   import std.stdio;
   writeln (ei);
   writeln (i);
   writeln (c);
}
```

gdc passes while dmd says:

```
$ dmd -unittest -main -run ini
ini.d(6): Error: non-constant expression `& bar`
ini.d(7): Error: non-constant expression `& bar`
```

Is this consistent?


Generate a pointer to a method of a struct

2022-10-14 Thread kdevel via Digitalmars-d-learn

Given a struct `S` with method `foo`: Any of these expressions
```
   
   
   &.S.foo
```
when they occur inside the struct they represent a delegate and 
not a function pointer. Is it okay to "extract" and use the 
function pointer from the delegate in this way:


```
struct S {
   void function () fp;
   void foo ()
   {
  fp = ().funcptr;
   }
   void bar ()
   {
  fp = ().funcptr;
   }
   auto fun () // invocation helper
   {
  if (! fp)
 fp = ().funcptr;
  void delegate () dg;
  dg.ptr = 
  dg.funcptr = fp;
  return dg ();
   }
}

unittest {
   S s;
   s.fun;
   s.fun;
}
```

In [1] Walter suggested to use a "lambda function" which reads 
(adopted to structs):


```
struct S {
   :
   void function (ref S) fp;
   :
   void foo () {
  :
  fun = function (ref S self) { return self.bar (); };
  :
   }
   :
}
```

dmd and gdc optimize the lambda invocations away. Nonetheless the 
expression looks somewhat too big. To overcome this I tried to 
generate the function pointer outside of the struct:


```
auto funcptr (alias method) ()
{
   return 
}
  :
  fun = funcptr!bar;
  :
```

Which works but neither dmd nor gdc were able to optimize the 
additional function call away. So I replaced the function call 
with a value:


```
template funcptr (alias method) {
   immutable funcptr =  // (*)
}
```

That code compiles under gdc 12.1 but I could not find any dmd 
version which compiles the code. All say


```
ptrtomethod.d(15): Error: non-constant expression `& bar`
```

Line 15 is the line I marked with `(*)`. Any comments?

[1] https://www.digitalmars.com/articles/b68.html
Member Function Pointers in D


Re: private method callable from other module

2022-10-08 Thread kdevel via Digitalmars-d-learn

On Saturday, 8 October 2022 at 15:56:01 UTC, Jack Pope wrote:
Altering the definition sequence in b.d to have the private 
version second has the desired result. Otherwise, when 
following private foo, it looks like public foo gets adopted as 
a public constructor. The same for classes.


Created Issue 23397 - private method callable from other module


Re: private method callable from other module

2022-10-08 Thread kdevel via Digitalmars-d-learn

On Saturday, 8 October 2022 at 10:05:33 UTC, kdevel wrote:

```
$ dmd -g -unittest -main -run a.d b.d
a.o: In function `_D1a16__unittest_L2_C1FZv':
(...)./a.d:5: undefined reference to `_D1b1S3fooMFhZv'
collect2: error: ld returned 1 exit status
Error: linker exited with status 1
```


`b.d` is the cmd line arg to the executable. The correct order of 
arguments to dmd is: `dmd -g -unittest -main b.d -run a.d`


Re: private method callable from other module

2022-10-08 Thread kdevel via Digitalmars-d-learn

On Saturday, 8 October 2022 at 09:59:17 UTC, kdevel wrote:

On Saturday, 8 October 2022 at 09:46:59 UTC, kdevel wrote:


```
$ dmd -g -unittest -main a.d b.d
$ ./a
void b.S.foo(ubyte c)
1 modules passed unittests
```


   2.086.1
   a.d(5): Error: struct `b.S` member foo is not accessible

   2.090.1
   compiles


Interestingly (again with dmd v2.100.2) `-run` runs into a link 
error:


```
$ dmd -g -unittest -main -run a.d b.d
a.o: In function `_D1a16__unittest_L2_C1FZv':
(...)./a.d:5: undefined reference to `_D1b1S3fooMFhZv'
collect2: error: ld returned 1 exit status
Error: linker exited with status 1
```


Re: private method callable from other module

2022-10-08 Thread kdevel via Digitalmars-d-learn

On Saturday, 8 October 2022 at 09:46:59 UTC, kdevel wrote:


```
$ dmd -g -unittest -main a.d b.d
$ ./a
void b.S.foo(ubyte c)
1 modules passed unittests
```


   2.086.1
   a.d(5): Error: struct `b.S` member foo is not accessible

   2.090.1
   compiles



private method callable from other module

2022-10-08 Thread kdevel via Digitalmars-d-learn

Is this a known bug?

```
// file b.d
import std.stdio;

struct S {
   private void foo (ubyte c)
   {
  writeln (__PRETTY_FUNCTION__);
   }
   void foo ()
   {
   }
}
```

```a.d
// file a.d
unittest {
   import b;
   auto s = S ();
   s.foo ('x');
}
```

```
$ dmd -g -unittest -main a.d b.d
$ ./a
void b.S.foo(ubyte c)
1 modules passed unittests
```


Re: Is `void` the correct way to say "do not initialize this variable"?

2022-10-06 Thread kdevel via Digitalmars-d-learn

On Monday, 3 October 2022 at 15:56:02 UTC, Paul Backus wrote:

Shouldn't this read

   Unspecified Value: If a void initialized variable's value 
is used

   before it is set, its value is unspecified.


Yes, it should. Many of the contributors to the D spec are not 
very well versed in the precise details of these terms, so 
mistakes like this occasionally slip through.


Issue 23390 - value of void initialized variable is unspecified 
(and not subject to UB)


Re: Is `void` the correct way to say "do not initialize this variable"?

2022-10-03 Thread kdevel via Digitalmars-d-learn

On Sunday, 2 October 2022 at 23:37:26 UTC, ryuukk_ wrote:
I got the answer thanks to IRC chat: 
https://dlang.org/spec/declaration.html#void_init


Quote:

   Implementation Defined: If a void initialized variable's value 
is used

   before it is set, its value is implementation defined.

Shouldn't this read

   Unspecified Value: If a void initialized variable's value is 
used

   before it is set, its value is unspecified.

?


chain of exceptions, next method

2022-08-13 Thread kdevel via Digitalmars-d-learn

Quote from `src/druntime/src`:

```
/**
 * Returns:
 * A reference to the _next error in the list. This is used 
when a new
 * $(D Throwable) is thrown from inside a $(D catch) block. 
The originally
 * caught $(D Exception) will be chained to the new $(D 
Throwable) via this

 * field.
 */
@property inout(Throwable) next() @safe inout return scope 
pure nothrow @nogc { return nextInChain; }


```

Testcode:

```
import std.stdio;
import std.exception;

private:

class E1 : Exception { mixin basicExceptionCtors; }
class E2 : Exception { mixin basicExceptionCtors; }

void foo ()
{
   try throw new E1 ("e1");
   catch (Exception e)
  throw new E2 ("e2");
}

void bar ()
{
   auto e = new E1 ("e1");
   e.next = new E2 ("e2");
   throw e;
}

void dumpall (Exception e)
{
   Throwable t = e;
   stderr.writeln ("dumpall");
   do
  stderr.writeln (t.msg);
   while ((t = t.next) !is null); // XXX: Why does !!(t = t.next) 
not compile?

}

public void main ()
{
   try foo ();
   catch (Exception e)
  dumpall (e);

   try bar ();
   catch (Exception e)
  dumpall (e);
}

$ dmd cetest
$ ./cetest
dumpall
e2
dumpall
e1
e2
```

Would have expected two chained Exceptions in both cases. Is it 
permitted to append exceptions from user code?




Re: How to use exceptions

2022-08-13 Thread kdevel via Digitalmars-d-learn
On Saturday, 13 August 2022 at 13:36:08 UTC, Christian Köstlin 
wrote:

[...]
1. error handling in main path: exactly thats what I would like 
todo. but for that the errors that raise need to have 
meaningful information. this is exactly what I am trying in 
those context* functions ... they do not do error handling, but 
more something like error enhancement (by fixing up the error 
information).


"Exception enrichment" would be my wording which is supported by 
google [1].
There is also the notion of "exception context" [2] and 
"contexted exception" [3].


2. yes ... for that the chain would need to be broken up, then 
you can react on the same exception classes of different 
members of the chain differently ... for that I do not see a 
nice way to write it in d.


The current filename imposes a context on its processing. The 
exception thrown from readText knows that filename and propagates 
it within the exception msg. Unfortunately exceptions are 
frequently only "stringly typed", e.g.


394: throw new JSONException("JSONValue is not a number type");
406: throw new JSONException("JSONValue is not a an integral 
type");


This should have been made into an exception hierarchy with the 
faulty value beeing a data member of the respective class. That 
would nicely support the crafting of a message for the user in 
the presentation layer.


Of course the UTF8Exception must be enriched with the filename in 
the application code.


3. localization is a fantastic example of data that needs to be 
added to almost every exception that raises from below.


How would you handle a FileException.msg = "myconfig.cnf: 
Permission denied"? Run regular expressions over the msg? 
Something is fundamentally wrong if any kind of parsing of error 
strings is required.


Then there is another type of user who shall not be faced with 
any kind of specific error message: The client of a company which 
runs a web application. This case is easy to implement: Catch any 
Exception and replace it with an "The Unforeseen happend, id#" 
message. Leave the code as it is and let the stack trace go into 
the error_log. The devops people of the company probably 
understand english messages.



[1] 
https://jenkov.com/tutorials/java-exception-handling/exception-enrichment.html


[2] 
https://docs.microsoft.com/en-us/dotnet/api/system.web.mvc.exceptioncontext?view=aspnet-mvc-5.2


[3] 
https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/exception/ContextedException.html




Re: How to use exceptions

2022-08-13 Thread kdevel via Digitalmars-d-learn
On Friday, 12 August 2022 at 21:41:25 UTC, Christian Köstlin 
wrote:



which would enable something like

```d
return  s
.readText
.parseJSON
.contextWithException((UTFException e) {
return new Exception("Cannot process UTF-8 in 
config file%s\n  %s".format(s, e.msg), e);

})
.contextWithException((FileException e) {
return new Exception("Cannot process config 
file%s\n %s".format(s, e.msg), e);

});
```


This is not as DRY as it could be. Furthermore I would try 
implement the error handling completely outside the main 
execution path, ideally in a wrapper around a the old main 
function (renamed to main_). This approach becomes problematic if 
exceptions of the same class can be thrown from two functions of 
the chain.


Your code is printing e.msg. How to you localize that string?




Re: Acess variable that was set by thread

2022-08-08 Thread kdevel via Digitalmars-d-learn

On Monday, 8 August 2022 at 17:45:03 UTC, bauss wrote:

On Monday, 8 August 2022 at 13:55:02 UTC, ag0aep6g wrote:

auto x = s.x;
[...]


Your problem is here and not because it was __gshared.

You're copying the value and obviously it can be changed in the 
meantime, that's common sense.


The value of `x` changes while `x` is being read.

You shouldn't use it like that. You should access s.x directly 
instead.


```
//auto x = s.x;
assert(s.x == 0 || s.x == -1, to!string(s.x, 16));
```

this replaces one race by three races which even prevents 
spotting the reason for the triggered assertion:


```
$ > ./race
core.exception.AssertError@race.d(40): 
```

And in the case of shared it can leave the same result if the 
reading thread locks first then it will read and process the 
value before it's changed.


???


code review: splitIds from DConf '22 day 3: saving a sort and "getting performance"

2022-08-04 Thread kdevel via Digitalmars-d-learn
At DConf '22 day 3 Robert Schadek presented at around 07:22:00 in 
the YT video the function `splitIds`. Given an HTML page from 
bugzilla containing a list of issues `splitIds` aims at 
extracting all bug-ids referenced within a specific url context:


```
long [] splitIds (string page)
{
   enum re = ctRegex!(`"show_bug.cgi\?id=[0-9]+"`);
   auto m = page.matchAll (re);

   return m
  .filter!(it => it.length > 0) // what is 
this?
  .map!(it => it.front) // whole 
match, it[0]
  .map!(it => it.find!(isNumber))   // searches 
fist number

  .map!(it => it.until!(it => !it.isNumber ())) // last number
  .filter!(it => !it.empty) // again an 
empty check??? why?

  .map!(it => it.to!long ())
  .uniq // .sort is 
missing. IMHO saving at the wrong things?

  .array;
}
```

`m` contains all matches. It is a "list of lists" as one would 
say in Perl. The "inner lists" contains as first element 
("`front`") the string which matches the whole pattern. So my 
first question is:


What is the purpose of the first filter call? Since the element 
of `m` is a match it cannot have a length of 0.


Then the code – and this took me some time to grasp – zooms into 
the match and tries to match the subexpression which starts with 
a number and ends with a number. But why does the author not use 
regular expression subexpression matching [1]? Is that really 
such an arcane discipline?


Next comes a filter call that seems to defend against the empty 
string. But there will be no empty string because `[0-9]+` only 
matches if there is at least one number.


Then there is something missing: Before the `uniq` call there is 
the assumption that bugzilla ordered the bugs already. What 
puzzles me is that on the one hand the author puts two find calls 
into the chain to guard against empty matches which cannot (?) 
happen but on the other hand ignores that the data may not be 
sorted. I mean the sortedness is nothing that the author of the 
function could control.


This is what my version of `splitIds` looks like:

```
long [] my_splitIds (string page)
{
   enum re = ctRegex!(`"show_bug.cgi\?id=([0-9]+)"`);
   auto m = page.matchAll (re);

   return m
  .map!(it => it[1]) // take the subexpression
  .map!(it => it.to!long ())
  .array
  .sort
  .uniq
  .array
  ;
}
```

For those who ask how one would write such a function in Perl:

```
sub splitIds ($)
{
   my $page = shift;
   my @ids = $page =~ m/"show_bug.cgi\?id=([0-9]+)"/g;
   my %hash = map { $_ => undef } @ids; # perl has no builtin uniq
   sort { $a <=> $b } keys %hash;   # force numeric sorting 
with <=>

}
```



[1] https://dlang.org/phobos/std_regex.html


Re: Combining JSON arrays into a single JSON array -- better way than this?

2022-08-01 Thread kdevel via Digitalmars-d-learn

On Monday, 1 August 2022 at 07:35:34 UTC, Christian Köstlin wrote:
[...]

```
An arguably shorter solution (that drops some of your logging) 
could be:


```d
import std;

void main() {
dirEntries(".", "*.json", SpanMode.shallow)
.filter!(f => !f.name.canFind("output"))
.map!(readText)
.map!(parseJSON)
.fold!((result, json) { result ~= json.array; return 
result; })

.toPrettyString
.reverseArgs!(std.file.write)("output-combined.json");
}
```


Is there an implementation which does not interpret the objects 
in the array:


Case 1
```
[{"A":"A","A":"B"}] -> [
{
"A": "B"
}
]
```

Case 2
```
[1.0001] -> [
1.0
]
```

Case 3
```
[] -> 
std.conv.ConvOverflowException@...Overflow in integral conversion

```





Re: Build for i586

2022-07-28 Thread kdevel via Digitalmars-d-learn

On Thursday, 28 July 2022 at 16:03:46 UTC, Alexander Zhirov wrote:
[...]

How did you manage to get hold of this compiler?

```
/root/usr/program/gcc/9.5.0/install/bin/cc
```


Where does this compiler come from?


This is an unpacked archive from an official source from the 
GNU website


https://ftp.mpi-inf.mpg.de/mirrors/gnu/mirror/gcc.gnu.org/pub/gcc/releases/gcc-9.5.0/


The archive `gcc-9.5.0.tar.gz` I found in that directory does not 
contain any binary compiler. The only "file" named "cc" is the 
directory


```
./gcc/testsuite/ada/acats/tests/cc
```


Re: Build for i586

2022-07-28 Thread kdevel via Digitalmars-d-learn

On Thursday, 28 July 2022 at 15:25:00 UTC, Alexander Zhirov wrote:
[...]

Everything falls on the same error.

```sh
checking for suffix of object files... configure: error: in 
`/home/thinstation/source/gcc/12.1.0/build/i586-pc-linux-gnu/libgcc':
configure: error: cannot compute suffix of object files: 
cannot compile

See `config.log' for more details


Have you looked into config.log? The errors are frequently 
located in the second half of the output.


In general, nothing happened. I've already tried everything. 
Here is the result, posted 
[here](https://pastebin.com/76gnneKZ).


In such cases I usually take the error message, here

``
configure: error: cannot compute suffix of object files:
``

and search with google for it. Google points me to stackoverflow:



```
This issue is caused by dyanmic link library path issue when the 
test programs try to link against libmpc/libmpfr/libgmp.


Append below environment variable to allow ld link against the 
correct so file:


export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/mpc/lib/

Then try build gcc again.
```

Does this help?


Re: Build for i586

2022-07-28 Thread kdevel via Digitalmars-d-learn

On Thursday, 28 July 2022 at 15:25:00 UTC, Alexander Zhirov wrote:

On Thursday, 28 July 2022 at 13:16:26 UTC, kdevel wrote:
On Thursday, 28 July 2022 at 12:45:51 UTC, Alexander Zhirov 
wrote:

[...]
I have already downloaded the latest GCC sources, nothing 
compiles anyway.


How did you manage to get hold of this compiler?

```
/root/usr/program/gcc/9.5.0/install/bin/cc
```


Where does this compiler come from?


Re: Some user-made C functions and their D equivalents

2022-07-28 Thread kdevel via Digitalmars-d-learn

On Thursday, 28 July 2022 at 14:57:36 UTC, pascal111 wrote:

[...]
Sure. What effect do YOU hope to causes or prevent by writing

```
/**/
```

between all of your functions?


I'm normal programmer, by mean that I'm not so expert in C 
matters to know really if there are particular patterns that 
have specific meanings for the compiler or not.


I was asking why /you/ put

```
/**/
```

between function definitions. You cannot or do not want to answer 
that question. I think that this pattern or habit is not your 
invention. You borrowed that style from someone else and did not 
ask him or her for its purpose. Right?





Re: Some user-made C functions and their D equivalents

2022-07-28 Thread kdevel via Digitalmars-d-learn

On Thursday, 28 July 2022 at 13:58:24 UTC, pascal111 wrote:
[...]
Precisely in what way? I am not kidding. I am seriously asking 
the question: In what way may a C or C++ compiler benefit from 
lines between functions which contain only comments consisting 
of nothing else than asterisks?


Seriously and accurately, if you meant that, we don't know how 
developers of C compilers programmed their compilers, for 
example, maybe there's a secret way the developers programmed 
their compiler so that a special pattern of comments can have a 
particular meaning to the compilers. We don't know! maybe it's 
true.


Sure. What effect do YOU hope to causes or prevent by writing

```
/**/
```

between all of your functions?



Re: Some user-made C functions and their D equivalents

2022-07-28 Thread kdevel via Digitalmars-d-learn

On Thursday, 28 July 2022 at 12:44:19 UTC, pascal111 wrote:

[...]
Do you think it helps the compiler if you put these

`/**/`

between your functions? Or is there anybody else who benefits 
from it?


"Do you think it helps the compiler if you put these"
Are you serious? maybe it's useful for compilers with some way.


Precisely in what way? I am not kidding. I am seriously asking 
the question: In what way may a C or C++ compiler benefit from 
lines between functions which contain only comments consisting of 
nothing else than asterisks?




Re: Build for i586

2022-07-28 Thread kdevel via Digitalmars-d-learn

On Thursday, 28 July 2022 at 12:45:51 UTC, Alexander Zhirov wrote:
[...]
I have already downloaded the latest GCC sources, nothing 
compiles anyway.


How did you manage to get hold of this compiler?

```
/root/usr/program/gcc/9.5.0/install/bin/cc
```


Everything falls on the same error.

```sh
checking for suffix of object files... configure: error: in 
`/home/thinstation/source/gcc/12.1.0/build/i586-pc-linux-gnu/libgcc':
configure: error: cannot compute suffix of object files: cannot 
compile

See `config.log' for more details


Have you looked into config.log? The errors are frequently 
located in the second half of the output.




Re: Some user-made C functions and their D equivalents

2022-07-28 Thread kdevel via Digitalmars-d-learn

On Thursday, 28 July 2022 at 12:25:05 UTC, pascal111 wrote:

[...]

ofix.c: In function 'fix':
ofix.c:7:3: warning: 'z' is used uninitialized 
[-Wuninitialized]

7 | y=modf(x,z);
  |   ^
ofix.c:5:12: note: 'z' was declared here
5 | double y,* z;
  |^
```

I would also like to complain about the double assignment to 
`y`.


"fix" function is the C version of BASIC standard one I made, 
it's the equivalent of "trunc" in D, but the code I programmed 
for "fix" was with TC++ , and it worked in DOS emulators with 
no problem,


"Code works" and "Code is correct" are two distinct categories. 
The compiler's warnings show that your code is not correct and 
not that it will necessarily not work. Incorrect code may work 
accidentally.


As a (future) software developer you are required to not just 
produce code that "works" "with no problem" but also code that is 
correct. "Correct" here means that the code adheres to the 
specifications of the language.


Writing incorrect code is like "fixing" a "broken" fuse with tin 
foil.


I have no idea how gcc will treat my code, but I think you are 
right that some other compilers will refuse such code, because 
VC++ 6 refused many of these functions codes I programmed with 
TC++ compiler.


The incorrectness of your C code does not depend on the compiler 
brand.


Re: Some user-made C functions and their D equivalents

2022-07-28 Thread kdevel via Digitalmars-d-learn

On Thursday, 28 July 2022 at 12:26:50 UTC, pascal111 wrote:

[...]
Aha! you mean "/**/", 
it has no job, just to separate between functions codes.


Do you think it helps the compiler if you put these

`/**/`

between your functions? Or is there anybody else who benefits 
from it?


Re: Some user-made C functions and their D equivalents

2022-07-28 Thread kdevel via Digitalmars-d-learn

On Wednesday, 27 July 2022 at 18:19:34 UTC, pascal111 wrote:
I made a library of some useful functions while I was studying 
C, and I'm curious to know if D has equivalents or some ones 
for some of my functions, or I have to retype 'em again in D.


The library link:
https://github.com/pascal111-fra/turbo-c-programs/blob/main/COLLECT2.H


1. What exact purpose do these

```
/**/
```

have?

2.
```
double fix(double x)
{

double y,* z;

y=modf(x,z);
y=*z;

return y;

}
```
Besides the remarkable formatting there is an issue with the 
code. According to the manual the modf function


```
double modf(double x, double *iptr);
```

stores "The integral part [of x] [...] in the location pointed to 
by iptr." If you ask the compiler for help (e.g. `gcc -Wall 
-pedantic`) it will tell you what's wrong:


```
ofix.c: In function 'fix':
ofix.c:7:3: warning: 'z' is used uninitialized [-Wuninitialized]
7 | y=modf(x,z);
  |   ^
ofix.c:5:12: note: 'z' was declared here
5 | double y,* z;
  |^
```

I would also like to complain about the double assignment to `y`.


Re: Build for i586

2022-07-28 Thread kdevel via Digitalmars-d-learn

On Thursday, 28 July 2022 at 10:39:06 UTC, Alexander Zhirov wrote:
[...]

I don't understand what I need to do.


You wrote

At first I thought that I needed to rebuild the GCC compiler 
for the i586
architecture. I downloaded GCC 9.5.0 and started the 
installation:


Then you wrote that this process failed. In your next post you 
quoted some code from the shell:


```
# /root/usr/program/gcc/9.5.0/install/bin/cc app.o -o app 
-L/root/usr/program/ldc/1.30/install/lib -lphobos2-ldc -ldrun
time-ldc -Wl,--gc-sections -lrt -ldl -lpthread -lm -m32 
-march=geode

# ./app
Illegal instruction
```

I read this as if you eventually succeeded in compiling your GCC 
9.5.0. If you repeat that build but use the switch


```
--with-arch-32=pentium3
```

in the configure command your generated GCC 9.5.0 will compile 
32-Bit code for the pentium3. I mean instead of


```
# ../source/configure --prefix=$PWD/../install_i586 
--enable-shared --enable-threads=posix --enable-__cxa_atexit 
--enable-clocale=gnu --enable-languages=c,c++,d 
--target=i586-pc-linux-gnu --disable-multilib 
--with-multilib-list=m32

```

type

```
# ../source/configure --prefix=$PWD/../install_i586 
--enable-shared --enable-threads=posix --enable-__cxa_atexit 
--enable-clocale=gnu --enable-languages=c,c++,d 
--target=i586-pc-linux-gnu --disable-multilib 
--with-multilib-list=m32 --with-arch-32=pentium3

```


Re: Some user-made C functions and their D equivalents

2022-07-28 Thread kdevel via Digitalmars-d-learn

On Thursday, 28 July 2022 at 00:46:19 UTC, pascal111 wrote:

On Thursday, 28 July 2022 at 00:36:54 UTC, ryuukk_ wrote:
I don't remember the exact syntax for GDC, but it should be 
pretty similar to DMD


You need to pass the module to the compiler

gdc main.d dcollect.d


I'm using CODE::BLOCKS IDE. How can I do it through it?


You should probably ask this question in a CODE::BLOCKS forum.

Further reading:

- Benefits of Not Using an IDE
  

- Why You Shouldn’t Always Use an IDE
  



Re: Build for i586

2022-07-28 Thread kdevel via Digitalmars-d-learn

On Thursday, 28 July 2022 at 06:12:49 UTC, Alexander Zhirov wrote:
On Thursday, 28 July 2022 at 06:01:17 UTC, Alexander Zhirov 
wrote:

```sh
/root/usr/program/gcc/9.5.0/install/bin/cc app.o -o app 
-L/root/usr/program/ldc/1.30/install/lib -lphobos2-ldc 
-ldruntime-ldc -Wl,--gc-sections -lrt -ldl -lpthread -lm -m32

```


So you eventually built GCC 9.5.0? I have used the

```
   --with-arch-32=pentium3
```

option in the configure step for compiling GCC 12.1.0. The build 
gdc

generates codes which successfully runs on my Pentium III.



Re: Particular exceptions names

2022-07-27 Thread kdevel via Digitalmars-d-learn

On Wednesday, 27 July 2022 at 09:35:12 UTC, Ali Çehreli wrote:

The following program show an example as well as 'enforce', 
which I prefer over explicit if+throw+else:


Me too.


  enforce!MissingArguments(args.length == 42,
   format!"Too few arguments: 
%s"(args.length));


However, this particular form lowers the readability a lot. It is 
not the absence of arguments which is enforced but the length of 
the args array, i.e. the presence of the arguments. Therefore I 
prefer


   enforce (args.length == 42, new MissingArguments (...));



Re: Particular exceptions names

2022-07-27 Thread kdevel via Digitalmars-d-learn

On Tuesday, 26 July 2022 at 23:43:59 UTC, pascal111 wrote:

In next example code, it used user-made exception,



[...]



   try {
  if( b == 0 ) {
 throw new Exception("Cannot divide by zero!");
  } else {
 result = format("%s",a/b);
  }



[...]



void main () {
   int x = 50;
   int y = 0;


What about the case x = -2147483648, y = -1?




Re: Choosing the correct compiler version

2022-07-20 Thread kdevel via Digitalmars-d-learn

On Tuesday, 19 July 2022 at 23:19:28 UTC, jfondren wrote:

Thanks for your thorough presentation.


[...]
Another option is to get newer glibc onto this system (not 
installing it, just making it available for dmd. use 
LD_LIBRARY_PATH).


On older systems the dynamic loader (ld.so) may not execute the 
binary under the new glibc with the error message "ELF file OS 
ABI invalid". This is due to the addition of two features to the 
toolchain (`STB_GNU_UNIQUE`, `STT_GNU_IFUNC`) eleven years ago 
[0] an application programmer usually does not have to deal with.


In this case one needs to start dmd using the loader which 
accompanies the new glibc. In order to avoid that I use patchelf 
to set `INTERP` and `RUNPATH` on all binaries in linux/bin64 
accordingly.



[...]
Speaking of toolchains, it might be possible to use a modern 
server with a modern dmd with an ancient glibc: 
https://www.lordaro.co.uk/posts/2018-08-26-compiling-glibc.html


Since glibc is not forward compatible [1] I wonder why the dmd 
tools are not routinely linked against a long established glibc 
version.


[0] 

[1] 





Re: Comparing Exceptions and Errors

2022-06-16 Thread kdevel via Digitalmars-d-learn
On Thursday, 16 June 2022 at 13:54:52 UTC, Steven Schveighoffer 
wrote:


[scope (success) lowered to finally]

[...]

Furthermore I always thought of scope guards as a means for 
cleanup. Cleanup implies in my eyes removing things which have 
been used in a previous task. This intended use is documented 
here:


https://tour.dlang.org/tour/en/gems/scope-guards

     Using scope guards makes code much cleaner and allows 
resource allocation
     and clean up code to be placed next to each other. These 
little helpers also
     improve safety because they make sure certain cleanup 
code is always called

     independent of which paths are actually taken at runtime.

Performing a COMMIT is rather the opposite of cleanup: It 
makes (writes) changes to the database persistent.


Semantically, you are just not undoing (rollback) the previous 
steps.


Objection! Not doing a rollback is not the same as doing a 
COMMIT. Even not "semantically". Until the COMMIT has succeeded 
none of the changed data of the transactions is visible in other 
DMBS sessions.




Re: Comparing Exceptions and Errors

2022-06-16 Thread kdevel via Digitalmars-d-learn

On Thursday, 16 June 2022 at 11:28:32 UTC, bauss wrote:
[...]

https://dlang.org/spec/statement.html#scope-guard-statement

Quote (again): "A [...] scope(success) statement may not exit 
with a throw [...]."

[...]
If the spec forbids it, but the compiler allows it, wouldn't it 
then be a bug?


What does "it" referer to? The code, throwing in scope guard? The 
spec? The compiler? [yes, no, no]


Re: Comparing Exceptions and Errors

2022-06-16 Thread kdevel via Digitalmars-d-learn
On Wednesday, 15 June 2022 at 20:46:56 UTC, Steven Schveighoffer 
wrote:

[...]
It has not harmed my code though. I tried throwing inside a 
scope guard, and it just works, I'm not sure why you can't 
throw in those?


You can but that is not acceptable for the spec explicitly 
forbids that:


https://dlang.org/spec/statement.html#scope-guard-statement

Quote (again): "A [...] scope(success) statement may not exit 
with a throw [...]."


Furthermore I always thought of scope guards as a means for 
cleanup. Cleanup implies in my eyes removing things which have 
been used in a previous task. This intended use is documented 
here:


https://tour.dlang.org/tour/en/gems/scope-guards

Using scope guards makes code much cleaner and allows 
resource allocation
and clean up code to be placed next to each other. These 
little helpers also
improve safety because they make sure certain cleanup code is 
always called

independent of which paths are actually taken at runtime.

Performing a COMMIT is rather the opposite of cleanup: It makes 
(writes) changes to the database persistent.


Re: Comparing Exceptions and Errors

2022-06-15 Thread kdevel via Digitalmars-d-learn
On Wednesday, 15 June 2022 at 03:09:56 UTC, Steven Schveighoffer 
wrote:
I don't see what you see wrong with the code I wrote. It's 
straightforward, obvious, and does the job I need it to do, in 
a way that's not prone to future mistakes.


Sometimes it is not easy to explain why code "feels" wrong and in 
the case of


```
   scope(success) conn.exec("COMMIT");
```

it was not that clear to me some days ago. The reason why I would 
not write
it is: `conn.exec("COMMIT")` may throw! Think of deferred 
constraints which are checked not before the commit. But "[a] 
[...] scope(success) statement may not exit with a throw [...]" 
[1]


[1] https://dlang.org/spec/statement.html#ScopeGuardStatement






Re: Comparing Exceptions and Errors

2022-06-14 Thread kdevel via Digitalmars-d-learn
On Monday, 13 June 2022 at 13:15:42 UTC, Steven Schveighoffer 
wrote:


Possibly, but I don't close the handle. It goes back to a pool 
to get reused.


Um. I need a (fresh) connection per CGI process. I wonder if 
nowadays the TLS startup between the browser and the webserver 
isn't at least one or two magnitudes more expensive than the 
(unencrypted) connection to the domain socket of the DB engine. 
May pooling DB connections instead of closing them be optimizing 
on the wrong end?



Why not have a Transaction class (struct)?


A transaction class/struct cannot hook normal return and 
throwing differently (the destructor has no way of knowing 
whether an exception is in flight).


Regarding C++: “[...] In a proper robust design, commits should 
always be explicit and destructors only rollback uncommitted 
transactions. [...]


There is now enough introspection in the language to actually 
implement implicit commit in a non exceptional path, but I think 
it would be a mistake."


[1] https://news.ycombinator.com/item?id=24648406


Re: Comparing Exceptions and Errors

2022-06-12 Thread kdevel via Digitalmars-d-learn
On Sunday, 5 June 2022 at 23:57:19 UTC, Steven Schveighoffer 
wrote:

On 6/5/22 6:09 PM, kdevel wrote:
On Sunday, 5 June 2022 at 20:53:32 UTC, Steven Schveighoffer 
wrote:

[...]
For this purpose nobody needs a separate subclass named 
`Error`. That works with `Exception`s.


You can use Exceptions instead. But the difference is they 
are part of the program instead of considered a check on the 
program itself.


I have no clue what that means.


An assert (or thrown error) is not ever supposed to happen, so 
it's not part of the program. It's a check to ensure that the 
program is sound and valid. You can feel free to insert as many 
asserts as you want, and it should not be considered part of 
the program.


It basically says "If this condition is false, this entire 
program is invalid, and I don't know how to continue from here."


Who is the narrator here? It is the author of the function which 
contains the assert. But this is not necessarily the author of 
the code which calls this function. Why should the author of the 
function be allowed *to terminate the whole the program* (be it 
via assert or exit)?



[...]
My code does not throw `Error`s. It always throws `Exception`s.


Then I guess you should just ignore Errors and let the runtime 
handle them? I'm not sure why this discussion is happening.


Because phobos/runtime throw Errors?

changing all range functions to use the `checkedPopFront` and 
`checkedFront`, just to find the error. Instead of letting 
the asserts do their job.


It is not clear to me, what you now complain about. You first 
criticized that in


```
for(auto r = range; !r.empty; r.popFront) {
    auto elem = r.front;
}
```

there is triple checking that r is not empty, namely in 
!r.empty, in r.front and in r.popFront. One check, !r.emtpy, 
will suffice. Hence one can safely use


```
for(auto r = range; !r.empty; r.popFront_unchecked) {
    auto elem = r.front_unchecked;
}
```


You can do this, and then if it fails, you have to guess that 
maybe you did something wrong, and start using the checked 
versions.


What shall go wrong in this example? Of course the compiler might 
generate wrong code. But it is not the aim of putting enforce and 
asserts into program code to guard against the bugs in the 
compiler.





Re: Comparing Exceptions and Errors

2022-06-12 Thread kdevel via Digitalmars-d-learn
On Tuesday, 7 June 2022 at 18:37:13 UTC, Steven Schveighoffer 
wrote:

[...]

My very common use of `scope(failure)` for my DB code:

```d
conn.exec("START TRANSACTION");
scope(success) conn.exec("COMMIT");
scope(failure) conn.exec("ROLLBACK");
```


Are there multiple (successful) returns in your code or why are 
you executing the COMMIT under a scope exit clause? If there is 
only one successful return wouldn't it enhance code readability 
when an explicit COMMIT precedes the return?


Is the ROLLBACK really necessary? Isn't the transaction not 
committed (i.e. rolled back) when the db handle is closed? Why 
not have a Transaction class (struct)?


Re: Comparing Exceptions and Errors

2022-06-05 Thread kdevel via Digitalmars-d-learn
On Sunday, 5 June 2022 at 21:08:11 UTC, Steven Schveighoffer 
wrote:

[...]
Just FYI, this is a *different discussion* from whether Errors 
should be recoverable.


The wording of this "question" bothers me really. What does 
"Errors" mean here? If you mean thrown object having a (sub)type 
of `Error` the relevant question is:


   ARE `Error`s recoverable?

If they ARE recoverable then every program can written in a way 
it handles even `Error`s gracefully.


Whether specific conditions are considered an Error or an 
Exception is something on which I have differing opinions than 
the language.


However, I do NOT have a problem with having an 
assert/invariant mechanism to help prove my program is correct.


I may be not a top-notch expert on this topic but IMO there is no 
facility which can perform such a proof.







Re: Comparing Exceptions and Errors

2022-06-05 Thread kdevel via Digitalmars-d-learn
On Sunday, 5 June 2022 at 20:53:32 UTC, Steven Schveighoffer 
wrote:

[...]
For this purpose nobody needs a separate subclass named 
`Error`. That works with `Exception`s.


You can use Exceptions instead. But the difference is they are 
part of the program instead of considered a check on the 
program itself.


I have no clue what that means.


[...]

If the code threw an `Exception` instead of an `Error` 
everything would be fine.


I think the point of Errors is that you can remove them for 
efficiency.


elephant/room.


Why? If you have a correct program, you shouldn't ever have 
errors thrown. If you do have errors thrown that's something 
you need to address ASAP.


My code does not throw `Error`s. It always throws `Exception`s.

In other words, just like asserts or bounds checks, they are 
not expected to be part of the normal working program.


"removing [Errors, asserts, bounds checks] is a bit like 
wearing a life-jacket to practice in the harbour, but then 
leaving the life-jackets behind when your ship leaves for open 
ocean" [1]


It's more like leaving the floaties behind when you are doing a 
swim meet.


Nice new question for job interviews.


[...]

Consider the normal flow of a range in a foreach loop, it's:

```d
// foreach(elem; range)
for(auto r = range; !r.empty; r.popFront) {
    auto elem = r.front;
}
```

If both `popFront` and `front` also always call `empty` you 
are calling `empty` 3 times per loop, with an identical value 
for the 2nd and 3rd calls.


Solution: Implement explicitly unchecked popFront() and 
front() versions.


That's terrible. Now I have to instrument my code whenever I 
have a weird unknown error,


Well, no. Just use the default. It will throw an exception if 
something goes wrong. Of course, I must admid, if you want to 
compete with those I-have-the-fastest-serving-http-server-guys 
(N.B.: HTTP not HTTPS! Did anybody notice that?) reporting 50 
Gigarequests per second (or so) then you probably have to 
*measure* *the* *performance* of the range/container 
implementation. But not earlier.


changing all range functions to use the `checkedPopFront` and 
`checkedFront`, just to find the error. Instead of letting the 
asserts do their job.


It is not clear to me, what you now complain about. You first 
criticized that in


```
for(auto r = range; !r.empty; r.popFront) {
   auto elem = r.front;
}
```

there is triple checking that r is not empty, namely in !r.empty, 
in r.front and in r.popFront. One check, !r.emtpy, will suffice. 
Hence one can safely use


```
for(auto r = range; !r.empty; r.popFront_unchecked) {
   auto elem = r.front_unchecked;
}
```

If you don't trust whomever you can simply keep the checked 
versions. The test will then be performed thrice regardless if a 
test failure will result in throwing an `Exception` or throwing 
an `Error`. AFAICS.


[...]


Re: Comparing Exceptions and Errors

2022-06-05 Thread kdevel via Digitalmars-d-learn

On Sunday, 5 June 2022 at 17:04:49 UTC, Ali Çehreli wrote:

On 6/5/22 08:07, kdevel wrote:

[...]
Like many other programmers who include me, Sean Parent may be 
right.[1]


Other than being a trivial example to make a point, the code 
I've shown may be taking advantage of the "structure of array" 
optimization.


"Premature optimization is ..."

[...]

> struct T {
> int a;
> int b;
> }
>
> struct S {
> T [] t;
>
>void add(int i) {
>  t ~= T (i, i * 10);
>}
>
>void foo() {
>  // Look Ma no assert!

The assert may have been moved to another place:


It's not "the" assert but another one. Nonetheless I take up the 
challenge:



struct T {
int a;
int b;

  invariant() {
// Look Pa it's still here!
assert(b == a * 10);
  }
}


struct T {
int i;
this (int i)
{
this.i = i;
import std.checkedint;
Checked!(int, Throw) (i) * 10;
}
int a () const { return i; }
int b () const { return i * 10; }
}
struct S {
const (T) [] t;
void add(int i) {// <-- Both arrays always same size
   t ~= T (i);
}
void foo() {
   // ...
}
}

void main() {
  auto s = S();
  s.add(42);
  s.foo();
//  s.a ~= 1; // does not compile
//  s.t[0].b = 3; // no compile either
//  s.t[0].i = 7; // cannot change i, does not compile
  s.add (2^^27); // fine
//  s.add (2^^28); // throws Overflow on binary operator, fine
  s.foo();
}


Ali


[...]

I'll try to not bring up his name again ;-)




Re: Comparing Exceptions and Errors

2022-06-05 Thread kdevel via Digitalmars-d-learn

On Sunday, 5 June 2022 at 14:24:39 UTC, Ali Çehreli wrote:
[...]

struct S {
  int[] a;
  int[] b;

  void add(int i) {// <-- Both arrays always same size
a ~= i;
b ~= i * 10;
  }

  void foo() {
assert(a.length == b.length);  // <-- Invariant check
// ...
  }
}

void main() {
  auto s = S();
  s.add(42);
  s.foo();
}

The code is written in a way that both arrays will *always* 
have equal number of elements.


I think this is what Sean Parent called "incidental data 
structure" [1]. I would refactor the code:


struct T {
   int a;
   int b;
}

struct S {
   T [] t;

  void add(int i) {
t ~= T (i, i * 10);
  }

  void foo() {
// Look Ma no assert!
// ...

  }
}

void main() {
  auto s = S();
  s.add(42);
  s.foo();
  s.a ~= 1; // does not compile
  s.foo();
}
```
[1] 


Re: Comparing Exceptions and Errors

2022-06-05 Thread kdevel via Digitalmars-d-learn

On Sunday, 5 June 2022 at 07:21:18 UTC, Ola Fosheim Grøstad wrote:
[...]
The reality is that software is layered. Faults at different 
layers should have different consequences at the discretion of 
a capable programmer.


+1


Re: Comparing Exceptions and Errors

2022-06-05 Thread kdevel via Digitalmars-d-learn
On Sunday, 5 June 2022 at 01:43:06 UTC, Steven Schveighoffer 
wrote:


[...]

But you aren't perfect, and so maybe you make a mistake, and 
trigger an Error. The compiler handles this unexpected 
condition by unwinding the stack back to the main function, 
printing the error and exiting, so you can go fix whatever 
mistake you made.


For this purpose nobody needs a separate subclass named `Error`. 
That works with `Exception`s.


[...]

If the code threw an `Exception` instead of an `Error` 
everything would be fine.


I think the point of Errors is that you can remove them for 
efficiency.


elephant/room.

In other words, just like asserts or bounds checks, they are 
not expected to be part of the normal working program.


"removing [Errors, asserts, bounds checks] is a bit like wearing 
a life-jacket to practice in the harbour, but then leaving the 
life-jackets behind when your ship leaves for open ocean" [1]


[...]

Consider the normal flow of a range in a foreach loop, it's:

```d
// foreach(elem; range)
for(auto r = range; !r.empty; r.popFront) {
auto elem = r.front;
}
```

If both `popFront` and `front` also always call `empty` you are 
calling `empty` 3 times per loop, with an identical value for 
the 2nd and 3rd calls.


Solution: Implement explicitly unchecked popFront() and front() 
versions.


Having the assert allows diagnosing invalid programs without 
crashing your program,


That depends on the understanding of "crashing a program". If 
library code throws an `Error` instead of an `Exception` I have 
to isolate that code in a subprocess in order to make my program 
gracefully handle the error condition.


Think of CGI processes which provide output direct to a customer. 
If there is an assert the customer will see the famous Internal 
Server Error message (in case of apache httpd).


[...]

[1] http://wiki.c2.com/?AssertionsAsDefensiveProgramming


Re: Comparing Exceptions and Errors

2022-06-05 Thread kdevel via Digitalmars-d-learn

On Sunday, 5 June 2022 at 00:40:26 UTC, Ali Çehreli wrote:
[...]
Errors are thrown when the program is discovered to be in an 
invalid state.


The following program throws an `Error` in popFront:

   import std.range;

   void main ()
   {
  int [1] a;
  auto q = a[1..$]; // line 6
  q.popFront;   // line 7, throws 
core.exception.AssertError

   }

When the program counter (PC) is at line 6 the program is in a 
valid state.


At no time the program is in an invalid state and it would not 
pass into an invalid state if popFront threw an `Exception` 
instead of an `Error`.


Re: Comparing Exceptions and Errors

2022-06-04 Thread kdevel via Digitalmars-d-learn
On Saturday, 4 June 2022 at 16:55:31 UTC, Steven Schveighoffer 
wrote:

[...]
The point of an `Error` is that your code can assume it cannot 
happen. If it does happen, the code is invalid.


According to my favorite dictionary "assume" means "take for 
granted" [1]. If `Error`s may happen how can code (or its author) 
"assume" that `Error`s cannot happen?


That makes absolutely no sense to me.

This is reflected in the fact that the compiler will omit 
cleanup code if an `Error` is thrown (it can assume that it 
will never happen).


But instead the compiler should *emit* the cleanup code and we 
would not have to discuss here carefully avoiding to name the 
root cause of all this entanglements.


The point of using `Error` is for a last resort check for 
program correctness (because you failed to validate the input 
before getting to that point).


If the code threw an `Exception` instead of an `Error` everything 
would be fine.



[...] I actually replaced some arrays with an
`Exception` throwing wrapper because I didn't want to crash the 
whole server for certain cases, and I didn't want to 
continuously validate array indexes.


+1


[...]
A great example are range functions. Often times you see at the 
beginning of any `popFront` method the statement 
`assert(!empty);`. This is universally accepted, as you 
shouldn't be calling `popFront` if you haven't checked for 
`empty`.


Yep.

```
core.exception.AssertError@[...]linux/bin64/../../src/phobos/std/range/primitives.d(2280):
 Attempting to popFront() past the end of an array of int
```

I see no difference to the potentially invalid array index case. 
It would ease the use of the range if it threw an `Exception`.


[1] https://www.thefreedictionary.com/assume


Re: Comparing Exceptions and Errors

2022-06-04 Thread kdevel via Digitalmars-d-learn

On Saturday, 4 June 2022 at 14:05:14 UTC, Paul Backus wrote:
[...]

   What does that mean? Am I `Error` blind?


Generally you do not need to subclass `Error` yourself. The 
most common way of throwing an `Error` in user code is to use 
`assert`, which (with default compiler flags) throws an 
`AssertError` on failure. Function contracts and struct/class 
invariants work the same way.


`git grep -Enw 'assert|unittest'` reveals that my code contains 
assert statements only in unittests. Someone (was it Walter?) 
once pointed out that asserts are ignored in relase mode (like C 
assert) and that for my purposes `enforce` (i.e. throw an 
Exception) is best suited.


3. Can you provide some piece of code which *must* throw 
`Error` and cannot

   throw an appropriate Exception?


This is entirely a question of API design. If it should be the 
caller's responsibility to check for some condition before 
calling the function, then you can throw an `Error` when that 
condition does not hold (or more likely, use an `assert` or an 
`in` contract to check for it).


Provided one does not catch `Error`s this means one has to 
isolate such an API design by using a subprocess. This is what 
one usually tries to avoid.


If it should be the callee's responsibility to check, you 
should throw an `Exception` (or use `enforce`).


If the library always throws exceptions it can be used in both 
API "designs". In the case that the implementor of the caller 
expects `Error`s instead of `Exceptions` she could use a small 
wrapper which catches the Exceptions and rethrows them as 
`Error`s. Likewise for error codes.


Using contracts and invariants impedes this approach.


Re: Comparing Exceptions and Errors

2022-06-04 Thread kdevel via Digitalmars-d-learn
On Friday, 3 June 2022 at 23:40:50 UTC, Steven Schveighoffer 
wrote:
During the last beerconf, I wrote a short blog post about how 
`Error` and `Exception` are different, and why you should never 
continue after catching `Error`s.


Feedback welcome, I didn't announce here when I wrote it 
because it's kind of small/insignificant, but maybe it can help 
newcomers to the language: 
https://www.schveiguy.com/blog/2022/05/comparing-exceptions-and-errors-in-d/


-Steve


Here my feedback:

1. What if div is called with x = -2147483648 and y = -1? Isn't 
code
   which allows a divisor == 0 to propagate to the CPU an error? 
Must
   the code thus not throw an object instantiated from a subclass 
of `Error`?


   What if I have that function div used in code which is called 
from say
   controller code of a CGI binary. Or likewise from a 
vibe.d-thread servicing
   a web request? How do I isolate that fault? Do I have to spawn 
a subprocess

   as Walter suggested in the case of memory corruption [1]?

   [This is of course all rhetorical!]

2. Since 2017 or so I have written some 10 KLOC of D, maybe about 
two dozen
   classes deriving from Exception. But I did not annotate any of 
my methods or
   function with "nothrow" nor did I author any class deriving 
from `Error`.


   What does that mean? Am I `Error` blind?

3. Can you provide some piece of code which *must* throw `Error` 
and cannot

   throw an appropriate Exception?

[1] http://forum.dlang.org/post/t6ef8c$1cu5$1...@digitalmars.com
Re: Why is D unpopular?



Re: dmd 2.099 regression: unittest -checkaction=context and import std.regex cause lots of undefined references

2022-05-28 Thread kdevel via Digitalmars-d-learn

On Friday, 18 March 2022 at 19:42:02 UTC, Anonymouse wrote:

On Thursday, 17 March 2022 at 14:00:45 UTC, kdevel wrote:
If ```import std.regex;``` is commented out or if 
```-checkaction=context``` is removed from the cmd line the 
unittest passes. Can anybody reproduce this?


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

File an issue, I'd say. The worst thing that can happen is that 
someone flags it as a duplicate.


Issue 22902 - dmd 2.099 regression: unittest -checkaction=context 
and import std.regex causes link error (edit)

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


Re: gdc 12.1: undefined references when linking separately compiled files

2022-05-28 Thread kdevel via Digitalmars-d-learn
On Saturday, 28 May 2022 at 15:10:25 UTC, Steven Schveighoffer 
wrote:

[...]
Is this specific to gdc, or does it happen for other compilers 
as well?


The former.


Re: gdc 12.1: undefined references when linking separately compiled files

2022-05-28 Thread kdevel via Digitalmars-d-learn

On Saturday, 28 May 2022 at 14:37:07 UTC, kdevel wrote:

dmd:

```
$ dmd -c ppinsta.d
$ dmd -c parser.d
$ dmd -of=ppinsta ppinsta.o parser.o
$ ./ppinsta
[]
```
(checking ldc/ldmd2 later)


```
$ ldc2 -c ppinsta.d && ldc2 -c parser.d && ldc2 -of=ppinsta 
ppinsta.o parser.o && ./ppinsta

[]

$ ldmd2 -c ppinsta.d && ldmd2 -c parser.d && ldmd2 -of=ppinsta 
ppinsta.o parser.o && ./ppinsta

[]
```

Both okay.


Re: gdc 12.1: undefined references when linking separately compiled files

2022-05-28 Thread kdevel via Digitalmars-d-learn

On Saturday, 28 May 2022 at 14:44:56 UTC, Adam D Ruppe wrote:

On Saturday, 28 May 2022 at 14:16:51 UTC, kdevel wrote:

$ gdc -o ppinsta ppinsta.d parser.d


Compiling together is faster anyway this is prolly what you 
want most the time.


But I know what's going on now, it is the template emission 
thing, the compiler thinks, since it is from std, it was 
already compiled somewhere else and skips it but it isn't 
actually there so the linker errors.


Using

gdc -fall-instantiations -c parser.d


   $ gdc -fall-instantiations -c ppinsta.d
   $ gdc -c parser.d
   $ gdc -o ppinsta ppinsta.o parser.o
   $ ./ppinsta
   []

Works. THX!


Re: gdc 12.1: undefined references when linking separately compiled files

2022-05-28 Thread kdevel via Digitalmars-d-learn

On Saturday, 28 May 2022 at 13:55:09 UTC, Tejas wrote:

On Saturday, 28 May 2022 at 13:12:46 UTC, kdevel wrote:
I am trying to build a project with GDC. It successfully 
compiles with dmd and ldmd2. When I use gdc in one go the 
binary is successfully build:


[...]


Is seperate compilation working successfully for dmd and ldc?


dmd:

```
$ dmd -c ppinsta.d
$ dmd -c parser.d
$ dmd -of=ppinsta ppinsta.o parser.o
$ ./ppinsta
[]
```
(checking ldc/ldmd2 later)

The only bug I know of regarding seperate compilation is 
https://issues.dlang.org/show_bug.cgi?id=20641





Re: gdc 12.1: undefined references when linking separately compiled files

2022-05-28 Thread kdevel via Digitalmars-d-learn

On Saturday, 28 May 2022 at 14:03:13 UTC, Adam D Ruppe wrote:

On Saturday, 28 May 2022 at 13:12:46 UTC, kdevel wrote:
gdc -o ppinsta ppinsta.o esah.o evaluate.o jsr.o jsw.o 
parser.o ptvr.o stack.o testdatagenerator.o


You might need to add -lgphobos or -lgphobos2 or whatever it is 
called too explicitly.


   gdc -v -o ppinsta ppinsta.o parser.o

It says

   
[...]gcc-12.1/bin/../libexec/gcc/x86_64-pc-linux-gnu/12.1.0/collect2 \

   [...]ppinsta.o parser.o -Bstatic -lgphobos [...]
^



Re: gdc 12.1: undefined references when linking separately compiled files

2022-05-28 Thread kdevel via Digitalmars-d-learn

On Saturday, 28 May 2022 at 13:12:46 UTC, kdevel wrote:

Any ideas?


ppinsta.d
```
import std.stdio : write, writeln;
import parser; // <- comment this out and gdc links

void main ()
{
   string [string] h;
   writeln (h);
}
```

parser.d
```
module parser;
import std.regex : regex;

private immutable auto VariableName = regex("^[a-zA-Z]*$");
```

Compile in one go:
```
$ gdc -o ppinsta ppinsta.d parser.d
$ ./ppinsta
[]
```

Compiled separately:
```
$ gdc -c ppinsta.d
$ gdc -c parser.d
$ gdc -o ppinsta ppinsta.o parser.o
ppinsta.o: In function 
`_D3std6format8internal5write__T8getWidthTAyaZQoFNaNfQlZl':
ppinsta.d:(.text+0x11ea): undefined reference to 
`_D3std9algorithm9searching__T3allSQBg6format8internal5write__T8getWidthTAyaZQoFQhZ9__lambda2Z__TQCpTQBcZQCxMFNaNfQBpZb'
ppinsta.o: In function 
`_D3std6format8internal5write__T8getWidthTAaZQnFNaNfQkZl':
ppinsta.d:(.text+0x16ba): undefined reference to 
`_D3std9algorithm9searching__T3allSQBg6format8internal5write__T8getWidthTAaZQnFQgZ9__lambda2Z__TQCoTQBbZQCwMFNaNfQBoZb'
ppinsta.o: In function 
`_D3std6format8internal5write__T20formatValueImplUlongTSQCb5array__T8AppenderTAyaZQoTaZQCdFNaNfKQBpmIbMKxSQDzQDy4spec__T10FormatSpecTaZQpZv':
ppinsta.d:(.text+0x21d9): undefined reference to 
`_D3std9algorithm9searching__T3allSQBg6format8internal5write__T20formatValueImplUlongTSQDg5array__T8AppenderTAyaZQoTaZQCdFKQBlmIbMKxSQFaQDu4spec__T10FormatSpecTaZQpZ10__lambda16Z__TQFvTAaZQGcMFNaNfQmZb'
ppinsta.d:(.text+0x2268): undefined reference to 
`_D3std9algorithm9searching__T3allSQBg6format8internal5write__T20formatValueImplUlongTSQDg5array__T8AppenderTAyaZQoTaZQCdFKQBlmIbMKxSQFaQDu4spec__T10FormatSpecTaZQpZ10__lambda17Z__TQFvTAaZQGcMFNaNfQmZb'
ppinsta.o: In function 
`_D3std6format8internal5write__T8getWidthTAwZQnFNaNbNiNfQoZl':
ppinsta.d:(.text+0x2996): undefined reference to 
`_D3std9algorithm9searching__T3allSQBg6format8internal5write__T8getWidthTAwZQnFQgZ9__lambda2Z__TQCoTQBbZQCwMFNaNbNiNfQBsZb'

collect2: error: ld returned 1 exit status
```




  1   2   3   4   >