Re: C-like static array size inference - how?

2022-06-06 Thread arandomonlooker via Digitalmars-d-learn

On Tuesday, 7 June 2022 at 00:20:31 UTC, Ali Çehreli wrote:

On 6/6/22 17:04, arandomonlooker wrote:

> [...]
syntax causes
> [...]

As you already know, the correct syntax is 'int[]' :) but it 
won't work because -betterC cannot support dynamic array.


[...]


Thank you. I was kind of distracted and i didn't type it 
correctly. Your solution works.


Re: want to confirm: gc will not free a non-gc-allocated field of a gc-allocated object?

2022-06-06 Thread max haughton via Digitalmars-d-learn

On Tuesday, 7 June 2022 at 00:40:56 UTC, ag0aep6g wrote:

On 07.06.22 00:22, max haughton wrote:
float[] doesn't contain pointers, so the GC won't do anything 
to or with it.


wat

float[] is a pointer (plus a length). The GC will deal with it 
like any other pointer.


I'm talking about the data in the array.

void[] might contain pointers, float[] does not so it won't be 
scanned. Or at least shouldn't be...


This is why you shouldn't use void[] for everything if you can 
help it.


```
void main()
{
import std.stdio;
auto voidArray = typeid(void[]);
auto floatArray = typeid(float[]);
writeln(voidArray.next.flags() & 1 );
writeln(floatArray.next.flags() & 1);
}
```


Re: want to confirm: gc will not free a non-gc-allocated field of a gc-allocated object?

2022-06-06 Thread ag0aep6g via Digitalmars-d-learn

On 07.06.22 00:22, max haughton wrote:
float[] doesn't contain pointers, so the GC won't do anything to or with 
it.


wat

float[] is a pointer (plus a length). The GC will deal with it like any 
other pointer.


Re: C-like static array size inference - how?

2022-06-06 Thread Ali Çehreli via Digitalmars-d-learn

On 6/6/22 17:04, arandomonlooker wrote:

> I usually transcribe them as follows, because the previous syntax causes
> a compiler error:
>
> ```d
> int numbersINeed[] = [1, 2, 3, 4, 5];
> ```

As you already know, the correct syntax is 'int[]' :) but it won't work 
because -betterC cannot support dynamic array.


> it's complaining about TypeInfo being absent.

What an unfortunate error message! Trying writeln() causes equally weird 
error messages.


> Can't i use some feature to imply that D must deduct the size
> from the array i am assigning, like an underscore? Can't D do that?

That request comes up relatively frequently. Currently, the only way I 
know of is to use std.array.staticArray:


import std.array;

extern (C)
void main() {
  auto numbersINeed = staticArray([1, 2, 3, 4, 5]);

  import std.range;
  import std.algorithm;
  import core.stdc.stdio;

  //  |
  //  V
  numbersINeed[].each!(n => printf("%d ", n));
}

Aside: I printed the elements with a range algorithm, which is not 
necessary at all. However, the reason I had to use it is because static 
arrays are not ranges because their lengths cannot change. [] takes a 
slice to all elements, which can reduce its length, and accordingly is a 
range.


Ali



C-like static array size inference - how?

2022-06-06 Thread arandomonlooker via Digitalmars-d-learn

Hello.
I am working on a project related to low-level development as a 
beginner, and i decided to pick D as the most optimal programming 
language for that, in large part because of it's strong 
integration with C and C++.
I happen to have a lot of arrays that i want to translate to D, 
formulated as follows (it's a unrelated example):


```c
int numbersINeed[] = {1, 2, 3, 4, 5};
```

I usually transcribe them as follows, because the previous syntax 
causes a compiler error:


```d
int numbersINeed[] = [1, 2, 3, 4, 5];
```

As i'm using the betterC mode, it's complaining about TypeInfo 
being absent. Can't i use some feature to imply that D must 
deduct the size from the array i am assigning, like an 
underscore? Can't D do that?

Thanks in advance to you all.


Re: Copy Constructor

2022-06-06 Thread Salih Dincer via Digitalmars-d-learn

On Sunday, 5 June 2022 at 15:45:17 UTC, Salih Dincer wrote:
Also, when we write to the screen with writeln(), why four 
times copy-constructors are running?


**Playground:** https://run.dlang.io/is/qHvLJe


I solved the problem by implementing the `toString()` member 
function. I also had to use a helper `writeout()` as below:


**struct Foo {**
```d
  string toString() {
     return format("%s", payload);
  }
```

**void main() {**
```d
  void writeout(T)(T text) {
    text.toString.writeln;/*
    import std.conv;
    text.to!string.writeln;//*/
  }
  writeout(three);
```
Interestingly, even using `to!string` the copy-constructor works 
extra +4 times! I think there will be performance losses if 
`write()` is used unconsciously everywhere! Although this way, it 
kisses with ctor +1 times :)


SDB@79




Re: want to confirm: gc will not free a non-gc-allocated field of a gc-allocated object?

2022-06-06 Thread H. S. Teoh via Digitalmars-d-learn
On Mon, Jun 06, 2022 at 10:18:08PM +, mw via Digitalmars-d-learn wrote:
> Hi,
> 
> Suppose I have this code:
> 
> ```
> class GCAllocated {
>   float[] data;
> 
>   this() {
> // non-gc-allocated field
> this.data = cast(float[])(core.stdc.stdlib.malloc(nBytes)[0 .. nBytes]);
>   }
> }
> 
> void foo() {
>   auto obj = new GCAllocated();  // gc-allocated owning object
>   ...
> }
> 
> ```
> 
> So when `obj` is cleanup by the GC, obj.data won't be freed by the GC:
> because the `data` is non-gc-allocated (and it's allocated on the
> non-gc heap), the GC scanner will just skip that field during a
> collection scan. Is this understanding correct?
> 
> I need this behavior for a special purpose, so I want to confirm it.
[...]

Short answer: yes, the GC will not do anything with that field.

Long answer: even if the GC wanted to do something about that field, how
could it? It has no information about how it was allocated. As far as
the GC is concerned, it's just a pointer + size pair, just like any
other array, and the pointer happens to point outside of GC-allocated
memory. Beyond that, the GC knows nothing else about the pointer. Is it
allocated by malloc? Is it pointing to static memory? Is it some
user-defined custom allocator? Is it some random garbage value?  Who
knows. The GC knows nothing about the pointer, so it conservatively
ignores it.

On a more general implementational note, D's GC is conservative, meaning
that if an aligned pointer-sized value looks like it might be a pointer
value, the GC will assume, erring on the side of being overly cautious,
that it *is* a pointer value, and mark any GC memory that it might
happen to point to as live.  The value could be an int or long, and the
GC wouldn't know any better. (More recent precise implementations may
skip some of these false positives, though.)  The same principle
applies, though: if the pointer has a value that the GC doesn't know
about (i.e., doesn't point to any of the known GC blocks) then the GC
will conservatively just ignore it.


T

-- 
Give a man a fish, and he eats once. Teach a man to fish, and he will sit 
forever.


Re: want to confirm: gc will not free a non-gc-allocated field of a gc-allocated object?

2022-06-06 Thread Guillaume Piolat via Digitalmars-d-learn

On Monday, 6 June 2022 at 22:24:45 UTC, Guillaume Piolat wrote:


My understanding is that while scanning, the GC will see the 
data.ptr pointer, but will not scan the area it points to since 
it's not in a GC range (the runtime can distinguish managed 
pointer and other pointers).


After scanning, when obj is non-reachable, the GC will destroy 
it but that won't lead to a reclaim of data.ptr since it knows 
it doesn't own that.


In D, the ownership of slice is purely determined by the memory 
area it points to.

If it points into GC memory then it's a GC slice.


Re: want to confirm: gc will not free a non-gc-allocated field of a gc-allocated object?

2022-06-06 Thread mw via Digitalmars-d-learn

On Monday, 6 June 2022 at 22:22:05 UTC, max haughton wrote:
float[] doesn't contain pointers, so the GC won't do anything 
to or with it.


does every array have a .ptr attr?

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

Dynamic Array Properties

.ptrReturns a pointer to the first element of the array.



Re: want to confirm: gc will not free a non-gc-allocated field of a gc-allocated object?

2022-06-06 Thread Guillaume Piolat via Digitalmars-d-learn

On Monday, 6 June 2022 at 22:18:08 UTC, mw wrote:
So when `obj` is cleanup by the GC, obj.data won't be freed by 
the GC: because the `data` is non-gc-allocated (and it's 
allocated on the non-gc heap), the GC scanner will just skip 
that field during a collection scan. Is this understanding 
correct?


My understanding is that while scanning, the GC will see the 
data.ptr pointer, but will not scan the area it points to since 
it's not in a GC range (the runtime can distinguish managed 
pointer and other pointers).


After scanning, when obj is non-reachable, the GC will destroy it 
but that won't lead to a reclaim of data.ptr since it knows it 
doesn't own that.




Re: want to confirm: gc will not free a non-gc-allocated field of a gc-allocated object?

2022-06-06 Thread max haughton via Digitalmars-d-learn

On Monday, 6 June 2022 at 22:18:08 UTC, mw wrote:

Hi,

Suppose I have this code:

```
class GCAllocated {
  float[] data;

  this() {
// non-gc-allocated field
this.data = cast(float[])(core.stdc.stdlib.malloc(nBytes)[0 
.. nBytes]);

  }
}

void foo() {
  auto obj = new GCAllocated();  // gc-allocated owning object
  ...
}

```

So when `obj` is cleanup by the GC, obj.data won't be freed by 
the GC: because the `data` is non-gc-allocated (and it's 
allocated on the non-gc heap), the GC scanner will just skip 
that field during a collection scan. Is this understanding 
correct?


I need this behavior for a special purpose, so I want to 
confirm it.


Thanks.


float[] doesn't contain pointers, so the GC won't do anything to 
or with it.


want to confirm: gc will not free a non-gc-allocated field of a gc-allocated object?

2022-06-06 Thread mw via Digitalmars-d-learn

Hi,

Suppose I have this code:

```
class GCAllocated {
  float[] data;

  this() {
// non-gc-allocated field
this.data = cast(float[])(core.stdc.stdlib.malloc(nBytes)[0 
.. nBytes]);

  }
}

void foo() {
  auto obj = new GCAllocated();  // gc-allocated owning object
  ...
}

```

So when `obj` is cleanup by the GC, obj.data won't be freed by 
the GC: because the `data` is non-gc-allocated (and it's 
allocated on the non-gc heap), the GC scanner will just skip that 
field during a collection scan. Is this understanding correct?


I need this behavior for a special purpose, so I want to confirm 
it.


Thanks.



Re: What happened to Circular Studio?

2022-06-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/6/22 3:46 PM, Jack wrote:
I just found out a game using D to develop games but later I see the 
last updates on the github, web site, twitter etc is from 2015. Does 
anyone knows what happend to the company?


It appears to be just a playground for a bunch of friends at RIT, I'm 
not sure how much of a "company" this was.


But, there is activity in the github issues list, circa November 2020: 
https://github.com/Circular-Studios/Dash/issues/249


But who knows, probably just fizzled out. I admit, I never heard of them.

-Steve


Re: What happened to Circular Studio?

2022-06-06 Thread Jack via Digitalmars-d-learn

for those that don't know: https://circularstudios.com/


What happened to Circular Studio?

2022-06-06 Thread Jack via Digitalmars-d-learn
I just found out a game using D to develop games but later I see 
the last updates on the github, web site, twitter etc is from 
2015. Does anyone knows what happend to the company?


Re: How to map machine instctions in memory and execute them? (Aka, how to create a loader)

2022-06-06 Thread rempas via Digitalmars-d-learn

On Monday, 6 June 2022 at 18:05:23 UTC, Johan wrote:
This instruction is wrong. Note that you are writing twice to 
RDX, but also that you are using `mov sign_extend imm32, reg64` 
instead of `mov imm64, reg64` (`0x48 0xBA`?). Third, why append 
an extra zero (`*cast(char*)(code + 32) = 0x00;`)? That must be 
a bug too.


cheers,
  Johan


Thanks! It seems that there is probably a "typo" from the 
original [source](https://github.com/vishen/go-x64-executable) 
that I got the code. The hex values are different however so 
there is only a mistake in the comment, the code normally works 
in the example repository (and I made a D version that works 
too). The padding in the end seems to be necessary else the 
example doesn't compile (I don't know why, I'm SUPER n00b when it 
comes to machine language, I don't know almost anything!). I'm 
also not sure how the "encode" will be for `mov imm64, reg64` as 
I tried to type what you typed in the parenthesis and it doesn't 
seem to work.


Re: Comparing Exceptions and Errors

2022-06-06 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

On Monday, 6 June 2022 at 18:08:17 UTC, Ola Fosheim Grøstad wrote:

There is no reason for D to undercut users of @safe code.


(Wrong usage of the term «undercut», but you get the idea…)




Re: Comparing Exceptions and Errors

2022-06-06 Thread Ola Fosheim Grøstad via Digitalmars-d-learn
On Monday, 6 June 2022 at 17:52:12 UTC, Steven Schveighoffer 
wrote:
Then that's part of the algorithm. You can use an Exception, 
and then handle the exception by calling the real sort. If in 
the future, you decide that it can properly sort with that 
improvement, you remove the Exception.


That is different from e.g. using a proven algorithm, like 
quicksort, but failing to implement it properly.


No? Why do you find it so? Adding a buggy optimization is exactly 
failing to implement it properly. There is a reference, the 
optimization should work exactly like the reference, but didn't.


Using asserts in @safe code should be no different than using 
asserts in Python code.


Python code <=> safe D code.

Python library implemented in C <=> trusted D code.

There is no reason for D to undercut users of @safe code. If 
anything D should try to use @safe to provide benefits that C++ 
users don't get.






Re: How to map machine instctions in memory and execute them? (Aka, how to create a loader)

2022-06-06 Thread Johan via Digitalmars-d-learn

On Monday, 6 June 2022 at 15:13:45 UTC, rempas wrote:

```
  // mov rdx, 
  *cast(char*)(code + 14) = 0x48;
  *cast(char*)(code + 15) = 0xC7;
  *cast(char*)(code + 16) = 0xC2;
  *cast(char*)(code + 17) = 12;
  *cast(char*)(code + 18) = 0x00;
  *cast(char*)(code + 19) = 0x00;
  *cast(char*)(code + 20) = 0x00;

  // mov rdx, 
  *cast(char*)(code + 21) = 0x48;
  *cast(char*)(code + 22) = 0xC7;
  *cast(char*)(code + 23) = 0xC1;
  *cast(long*)(code + 24) = cast(long)data;
  *cast(char*)(code + 32) = 0x00;
  ```


This instruction is wrong. Note that you are writing twice to 
RDX, but also that you are using `mov sign_extend imm32, reg64` 
instead of `mov imm64, reg64` (`0x48 0xBA`?). Third, why append 
an extra zero (`*cast(char*)(code + 32) = 0x00;`)? That must be a 
bug too.


cheers,
  Johan



Re: Comparing Exceptions and Errors

2022-06-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/6/22 12:15 PM, Ola Fosheim Grøstad wrote:

On Monday, 6 June 2022 at 15:54:16 UTC, Steven Schveighoffer wrote:
If it's an expected part of the sorting algorithm that it *may fail to 
sort*, then that's not an Error, that's an Exception.


No, it is not expected. Let me rewrite my answer to Sebastiaan to fit 
with the sort scenario:


For instance, you may have a formally verified sort function, but it is 
too slow. So you optimize one selected bottle neck, but that cannot be 
verified, because verification is hard. That specific unverified 
softspot is guarded by an assert. The compiler may remove it or not.


Your shipped product fails, because the hard to read optimization wasn't 
perfect. So you trap the thrown assert and call the reference 
implementation instead.


The cool thing with actors/tasks is that you can make them as small and 
targeted and revert to fallbacks if they fail.


(Assuming 100% @safe code.)


Then that's part of the algorithm. You can use an Exception, and then 
handle the exception by calling the real sort. If in the future, you 
decide that it can properly sort with that improvement, you remove the 
Exception.


That is different from e.g. using a proven algorithm, like quicksort, 
but failing to implement it properly.


-Steve


Re: Comparing Exceptions and Errors

2022-06-06 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

On Monday, 6 June 2022 at 16:15:19 UTC, Ola Fosheim Grøstad wrote:
On Monday, 6 June 2022 at 15:54:16 UTC, Steven Schveighoffer 
wrote:
If it's an expected part of the sorting algorithm that it *may 
fail to sort*, then that's not an Error, that's an Exception.


No, it is not expected. Let me rewrite my answer to Sebastiaan 
to fit with the sort scenario:


Let me sketch up another scenario. Let's say I am making an 
online game and I need early feedback from beta-testers. So I run 
my beta-service with lots of asserts and logging, when actors 
fail I discard them and relaunch them.


If the server went down on the first assert I wouldn't be able to 
test my server at all, because there would be no users willing to 
participate in a betatest where the server goes down every 20 
seconds! That is a very bad high risk-factor, that totally 
dominates this use scenario.


An engineer has to fill words such as «reliability», «utility», 
«probability» and «risk» with meaning that match the use scenario 
and make deliberate choices (cost-benefit-risk considerations). 
That includes choosing an actor model, and each actor has to 
prevent failure from affecting other actors. (by definition of 
«actor»).





Re: How to map machine instctions in memory and execute them? (Aka, how to create a loader)

2022-06-06 Thread rempas via Digitalmars-d-learn

On Monday, 6 June 2022 at 16:24:58 UTC, Guillaume Piolat wrote:


See:
https://github.com/GhostRain0/xbyak
https://github.com/MrSmith33/vox/blob/master/source/vox/utils/mem.d


Thank you! And I just noticed that the second source is from 
Vox


Re: How to map machine instctions in memory and execute them? (Aka, how to create a loader)

2022-06-06 Thread rempas via Digitalmars-d-learn

On Monday, 6 June 2022 at 16:08:28 UTC, Adam D Ruppe wrote:


On a lot of systems, it can't be executable and writable at the 
same time, it is a security measure.


see https://en.wikipedia.org/wiki/W%5EX


so you might have to mprotect it to remove the write permission 
before trying to execute it.


idk though


Thank you! This was very helpful and I can see why it is a clever 
idea to not allow it (and I love that OpenBSD was the first 
introducing it!!) and I love security stuff ;)


However, even with "mprotect" or If I just use "PROT_READ" and 
"PROT_EXEC", it still doesn't work so there should be something 
else I'm doing wrong...


Re: How to map machine instctions in memory and execute them? (Aka, how to create a loader)

2022-06-06 Thread Guillaume Piolat via Digitalmars-d-learn

On Monday, 6 June 2022 at 15:13:45 UTC, rempas wrote:


Any ideas?


See:
https://github.com/GhostRain0/xbyak
https://github.com/MrSmith33/vox/blob/master/source/vox/utils/mem.d





Re: Comparing Exceptions and Errors

2022-06-06 Thread Ola Fosheim Grøstad via Digitalmars-d-learn
On Monday, 6 June 2022 at 15:54:16 UTC, Steven Schveighoffer 
wrote:
If it's an expected part of the sorting algorithm that it *may 
fail to sort*, then that's not an Error, that's an Exception.


No, it is not expected. Let me rewrite my answer to Sebastiaan to 
fit with the sort scenario:


For instance, you may have a formally verified sort function, but 
it is too slow. So you optimize one selected bottle neck, but 
that cannot be verified, because verification is hard. That 
specific unverified softspot is guarded by an assert. The 
compiler may remove it or not.


Your shipped product fails, because the hard to read optimization 
wasn't perfect. So you trap the thrown assert and call the 
reference implementation instead.


The cool thing with actors/tasks is that you can make them as 
small and targeted and revert to fallbacks if they fail.


(Assuming 100% @safe code.)

It says that the programmer cannot attribute exactly where this 
went wrong because otherwise, he would have accounted for it, 
or thrown an Exception instead (or some other mitigation).


He can make a judgement. If this happened in a safe pure function 
then it would most likely be the result of what is what meant to 
do: check that the assumptions of the algorithm holds.



Anything from memory corruption, to faulty hardware, to bugs in 
the code, could be the cause.


That is not what asserts check! They will be removed if the 
static analyzer is powerful enough. All the information to remove 
the assert should be in the source code.


You are asserting that *given all the constraints of the type 
system* then the assert should hold.


Memory corruption could make an assert succeed when it should 
not, because then anything can happen! It cannot catch memory 
corruption reliably because it is not excluded from optimization. 
You need something else for that, something that turns off 
optimization for all asserts.




Exactly. Use Exceptions if it's recoverable, Errors if it's not.


This is what is not true, asserts says only something about the 
algorithm it is embedded in, it says that the algorithm makes a 
wrong assumption, and that is all. It says nothing about the 
calling environment.



A failed assert could be because of undefined behavior. It 
doesn't *imply* it, but it cannot be ruled out.


And a successful assert could happen because of undefined 
behaviour or optimization! If you want these types of guards then 
you need to propose a type of asserts that would be excluded from 
optimization. (which might be a good idea!)


In the case of UB anything can happen. It is up to the programmer 
to make that judgment based on the use scenario. It is a matter 
of probabilisitic calculations in relation to the use scenario of 
the application.


As I pointed out elsewhere: «reliability» has to be defined in 
terms of the use scenario by a skilled human being, not in terms 
of some kind of abstract thinking about compiler design.






Re: How to map machine instctions in memory and execute them? (Aka, how to create a loader)

2022-06-06 Thread Adam D Ruppe via Digitalmars-d-learn

On Monday, 6 June 2022 at 15:13:45 UTC, rempas wrote:
  void* code = mmap(null, cast(ulong)500, PROT_READ | 
PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);


On a lot of systems, it can't be executable and writable at the 
same time, it is a security measure.


see https://en.wikipedia.org/wiki/W%5EX


so you might have to mprotect it to remove the write permission 
before trying to execute it.


idk though


Re: How to map machine instctions in memory and execute them? (Aka, how to create a loader)

2022-06-06 Thread rempas via Digitalmars-d-learn

On Monday, 6 June 2022 at 15:27:12 UTC, Alain De Vos wrote:
Note , it is also possible to do inline assembly with asm{...}  
or __asm(T) {..}.


Thank you for the info! I am aware of that, I don't want to 
practically do this. I just want to learn how it works. It will 
be useful when I'll built my own OS.


Re: Comparing Exceptions and Errors

2022-06-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/6/22 12:59 AM, Ola Fosheim Grøstad wrote:

On Sunday, 5 June 2022 at 23:57:19 UTC, Steven Schveighoffer wrote:
It basically says "If this condition is false, this entire program is 
invalid, and I don't know how to continue from here."


No, it says: this function failed to uphold this invariant. You can 
perfectly well recover if you know what that function touches.


For instance if a sort function fails, then you can call a slower sort 
function.


If it's an expected part of the sorting algorithm that it *may fail to 
sort*, then that's not an Error, that's an Exception.




Or in terms of actors/tasks: if one actor-solver fails numerically, then 
you can recover and use a different actor-solver.


If the condition is recoverable => Exception. If it is not recoverable 
=> Error.



An assert says nothing about the whole program.


An assert says that something is wrong, and this was not expected or 
foreseen. It says that the programmer cannot attribute exactly where 
this went wrong because otherwise, he would have accounted for it, or 
thrown an Exception instead (or some other mitigation). Anything from 
memory corruption, to faulty hardware, to bugs in the code, could be the 
cause.




An assert only says that the logic of that particular function is not 
meeting the SPEC.


That's one possible reason. But if you are *planning* on possibly not 
meeting the spec (such as your sort example), that is a different story.



Only the programmer knows if recovery is possible, not the compiler.


Exactly. Use Exceptions if it's recoverable, Errors if it's not.


A failed assert is not implying undefined behaviour in @safe code.


A failed assert could be because of undefined behavior. It doesn't 
*imply* it, but it cannot be ruled out.


-Steve


Re: How to map machine instctions in memory and execute them? (Aka, how to create a loader)

2022-06-06 Thread Alain De Vos via Digitalmars-d-learn
Note , it is also possible to do inline assembly with asm{...}  
or __asm(T) {..}.


How to map machine instctions in memory and execute them? (Aka, how to create a loader)

2022-06-06 Thread rempas via Digitalmars-d-learn
I tried to find anything that will show code but I wasn't able to 
find anything expect for an answer on stackoverflow. I would find 
a lot of theory but no practical code that works. What I want to 
do is allocate memory (with execution mapping), add the machine 
instructions and then allocate another memory block for the data 
and finally, execute the block of memory that contains the code. 
So something like what the OS loader does when reading an 
executable. I have come with the following code:


```d
import core.stdc.stdio;
import core.stdc.string;
import core.stdc.stdlib;
import core.sys.linux.sys.mman;

extern (C) void main() {
  char* data = cast(char*)mmap(null, cast(ulong)15, 
PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);

  memset(data, 0x0, 15); // Default value

  *data = 'H';
  data[1] = 'e';
  data[2] = 'l';
  data[3] = 'l';
  data[4] = 'o';
  data[5] = ' ';

  data[6] = 'w';
  data[7] = 'o';
  data[8] = 'r';
  data[9] = 'l';
  data[10] = 'd';
  data[11] = '!';

  void* code = mmap(null, cast(ulong)500, PROT_READ | PROT_WRITE 
| PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);

  memset(code, 0xc3, 500); // Default value

  /* Call the "write" and "exit" system calls*/
  // mov rax, 0x04
  *cast(char*)code = 0x48;
  *cast(char*)(code + 1) = 0xC7;
  *cast(char*)(code + 2) = 0xC0;
  *cast(char*)(code + 3) = 0x04;
  *cast(char*)(code + 4) = 0x00;
  *cast(char*)(code + 5) = 0x00;
  *cast(char*)(code + 6) = 0x00;

  // mov rbx, 0x01
  *cast(char*)(code + 7)  = 0x48;
  *cast(char*)(code + 8)  = 0xC7;
  *cast(char*)(code + 9)  = 0xC3;
  *cast(char*)(code + 10) = 0x01;
  *cast(char*)(code + 11) = 0x00;
  *cast(char*)(code + 12) = 0x00;
  *cast(char*)(code + 13) = 0x00;

  // mov rdx, 
  *cast(char*)(code + 14) = 0x48;
  *cast(char*)(code + 15) = 0xC7;
  *cast(char*)(code + 16) = 0xC2;
  *cast(char*)(code + 17) = 12;
  *cast(char*)(code + 18) = 0x00;
  *cast(char*)(code + 19) = 0x00;
  *cast(char*)(code + 20) = 0x00;

  // mov rdx, 
  *cast(char*)(code + 21) = 0x48;
  *cast(char*)(code + 22) = 0xC7;
  *cast(char*)(code + 23) = 0xC1;
  *cast(long*)(code + 24) = cast(long)data;
  *cast(char*)(code + 32) = 0x00;

  // int 0x80
  *cast(char*)(code + 33) = 0xcd;
  *cast(char*)(code + 34) = 0x80;

  /* Execute the code */
  (cast(void* function()))();
}
```

I'm 100% sure that the instructions work as I have tested them 
with another example that creates an ELF executable file and it 
was able to execute correctly. So unless I copy-pasted them 
wrong, the instructions are not the problem. The only thing that 
may be wrong is when I'm getting the location of the "data" 
"segment". In my eyes, this uses 8 bytes for the memory address 
(I'm in a 64bit machine) and it takes the memory address the 
"data" variable holds so I would expect it to work


Any ideas?


Re: Comparing Exceptions and Errors

2022-06-06 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

On Monday, 6 June 2022 at 06:56:46 UTC, Ola Fosheim Grøstad wrote:

On Monday, 6 June 2022 at 06:14:59 UTC, Sebastiaan Koppe wrote:

Those are not places where you would put an assert.

The only place to put an assert is when *you* know there is no 
recovery.


No, asserts are orthogonal to recovery. They just specify the 
assumed constraints in the implementation of the algorithm. You 
can view them as comments that can be read by a computer and 
checked for that specific function.


I guess an informal way to express this is:

*Asserts are comments that you would need to make when explaining 
why the algorithm works to another person (or to convince 
yourself that it works).*


As far as unnecessary asserts, it would be nice to have something 
more powerful than static assert, something that could reason 
about runtime issues that are simple and issue errors if it could 
not establish it. E.g.:

```
int i = 0;
…later…
i++;
…much later…
compiletime_assert(i>0);
```



Re: Copy Constructor

2022-06-06 Thread Ali Çehreli via Digitalmars-d-learn

On 6/5/22 14:57, Ali Çehreli wrote:

> struct Foo {
>Foo dup() {
>  auto result = Foo(this.payload);
>  // ...
>  return result;
>}
> }
>
> In that case, the "named return value optimization" (NRVO) would be
> applied and the object would still be moved to 'x'.

I am wrong there as well: Technically, NRVO (or RVO) does not move but 
constructs the object in the caller's stack frame.


So, if the caller has the following code:

  auto z = existing.dup();

Then 'result' inside dup() is the same as caller's 'z'. Not 'result' but 
'z' would be constructed in dup(). No move is performed and no value is 
actually returned.


Ali



Re: Comparing Exceptions and Errors

2022-06-06 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

On Monday, 6 June 2022 at 06:14:59 UTC, Sebastiaan Koppe wrote:

Those are not places where you would put an assert.

The only place to put an assert is when *you* know there is no 
recovery.


No, asserts are orthogonal to recovery. They just specify the 
assumed constraints in the implementation of the algorithm. You 
can view them as comments that can be read by a computer and 
checked for that specific function.


For instance you can have a formally proven reference 
implementation full of asserts, then one optimized version where 
you keep critical asserts or just the post condition. If the 
optimized version fails, then you can revert to the reference 
(with no or few asserts, because it is already formally verified).


There is nothing wrong with having many asserts or asserts you 
«know» to hold. They are helpful when you modify code and 
datastructures.


Maybe one could have more selective ways to leave out asserts 
(e.g. based on revision) so that you remove most asserts in 
actors that has not changed since version 1.0 and retain more 
asserts in new actors.


Also, if you fully check the full post condition (in @safe code) 
then you can remove all asserts in release as they are 
inconsequential.


So the picture is more nuanced and it should be up to the 
programmer to decide, but maybe a more expressive and selective 
regime is useful.


Re: Comparing Exceptions and Errors

2022-06-06 Thread Sebastiaan Koppe via Digitalmars-d-learn

On Monday, 6 June 2022 at 04:59:05 UTC, Ola Fosheim Grøstad wrote:
For instance if a sort function fails, then you can call a 
slower sort function.


Or in terms of actors/tasks: if one actor-solver fails 
numerically, then you can recover and use a different 
actor-solver.


Those are not places where you would put an assert.

The only place to put an assert is when *you* know there is no 
recovery.


Like you have been arguing, there aren't many places like that.

So don't use it.

---

9 out of 10 times when I see an assert in code review I ask the 
author to reconsider. Often it only requires a little tweak.


I guess you could say I have found asserts to be misused.