Re: How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?

2023-10-17 Thread rempas via Digitalmars-d-learn

On Sunday, 15 October 2023 at 07:22:53 UTC, Imperatorn wrote:
You already got a lot of good answers, I thought I'd just share 
this for anyone searching for nogc string formatting compatible 
with betterC:


https://code.dlang.org/packages/bc-string


You thought, well, thank you very much and have a great day!


Re: How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?

2023-10-14 Thread rempas via Digitalmars-d-learn

On Friday, 13 October 2023 at 10:11:33 UTC, Nick Treleaven wrote:


You can also do it using a string mixin:

mixin(create_fn!(mixin("`", i, "`")));

I think that's equivalent to `i.stringof` anyway.


Thank you for the info!


Re: How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?

2023-10-14 Thread rempas via Digitalmars-d-learn

On Tuesday, 10 October 2023 at 16:11:57 UTC, bachmeier wrote:


Which part uses Phobos? The linked function compiles without 
importing anything.


Actually, you are right. I didn't give a lot of thought to it, as 
there is the line `char[] ret = new char[](length);` but I can 
replace it with an external buffer. Anyway, I'm not trying to do 
that anymore, and I will also create my own `int_to_string` 
method in the future but thanks for pointing it out!


Re: How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?

2023-10-10 Thread rempas via Digitalmars-d-learn

On Tuesday, 10 October 2023 at 11:46:38 UTC, Hipreme wrote:
My engine has its own implementation of toString(long), which 
does not have dependency with the C runtime:


https://github.com/MrcSnm/HipremeEngine/blob/master/modules/util/source/hip/util/conv.d#L180C1-L208C2

I have reimplemented the entire conv module since it is one of 
mostly used module and it pulled down a lot of things, so, with 
my util module I was able to make my program much smaller too.


Thank you for the idea! However, your code used Phobos which I 
don't want to use so it will not do.


Re: How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?

2023-10-10 Thread rempas via Digitalmars-d-learn

On Tuesday, 10 October 2023 at 11:45:25 UTC, Dennis wrote:
The result of `.stringof` is implementation defined, it can be 
used for debugging but don't make your program's semantics 
depend on the output of it.


...

...

...That being said, this trick can be used to convert an 
integer to string at compile time:



```D
enum itoa(int i) = i.stringof;

static foreach(i; 0 .. 10) {
  mixin(create_fn!(itoa!i));
}
```

Technically not reliable, but I don't expect integers to ever 
get printed differently than a string of base 10 digits.


Thank you! It is great and works great. I will however use the 
example from Imperatorn as it does not use ".stringof". Have an 
amazing day!


Re: How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?

2023-10-10 Thread rempas via Digitalmars-d-learn

On Tuesday, 10 October 2023 at 05:32:52 UTC, Imperatorn wrote:

If count < 10 then why not just

```d
import std;

static foreach(c; "0123456789")
{
  mixin(create_fn!(c));
}

enum create_fn(char num) = `
  auto function_`~ num ~`()
=> "Hello from function `~ num ~`!";
`;

void main()
{
  assert(function_9() == "Hello from function 9!");
}
```


Thank you! Yeah, the most clean code wins for me, so I'll use 
yours (if it's open source, lol)! Thank you and have an amazing 
day!


Re: How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?

2023-10-10 Thread rempas via Digitalmars-d-learn

On Monday, 9 October 2023 at 22:49:11 UTC, Salih Dincer wrote:
Great masters generally warn to stay away from stringof. Please 
do not use it as much as possible. The following code snippet 
will be useful to you:


```d
alias CN = __traits(allMembers, CardinalNumbers);

static foreach(i; CN)
{
  mixin(create_fn!(i[1]));
}

enum create_fn(char num) = `
  auto function_`~ num ~`()
    => "Hello from function `~ num ~`!";
`;

enum CardinalNumbers
{
  n0, n1, n2, n3, n4, n5, n6, n7, n8, n9
}

void main()
{
  assert(function_9() == "Hello from function 9!");
}
```

SDB@79


Thank you so much! This will do the trick. Have a beautiful day!


Re: How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?

2023-10-09 Thread rempas via Digitalmars-d-learn

On Monday, 9 October 2023 at 17:52:58 UTC, Jonathan M Davis wrote:


The closest to a built-in solution would be toString on classes 
and structs, but structs don't necessarily have a toString. 
Rather, in many cases, Phobos does introspection on the struct 
to figure out how to convert the struct's members to a string 
if no toString is present (which isn't necessarily pretty but 
generally works well for debug output). Anyone looking to be 
able to do that sort of thing without Phobos is either going to 
need to reimplement what Phobos does themselves or use a third 
party library that already does that.


[...]


Thank you for the info. Unfortunately, while my project uses 
libc, I try to get rid of it as well, so it will also not do. I 
may create a function in the future myself. Thanks a lot for your 
time and I hope you have a beautiful day!


Re: How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?

2023-10-09 Thread rempas via Digitalmars-d-learn

On Monday, 9 October 2023 at 17:42:48 UTC, Imperatorn wrote:


You could just add your own int to string I guess?


That will be a good idea! I'll do it in the future if that is the 
case, as it's not important, and I want to finish my job. Thank 
you and have a great day!


Re: How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?

2023-10-09 Thread rempas via Digitalmars-d-learn

On Monday, 9 October 2023 at 16:53:55 UTC, mw wrote:


but you `import std.stdio;`?

Or copy the std/conv.d over to your build,

or copy / write a toString(int) function yourself, which is 
compile-time callable.


I do on that example just to use "write". It wouldn't be 
necessary, but I just included it. My normal project does not use 
Phobos.


Re: How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?

2023-10-09 Thread rempas via Digitalmars-d-learn

On Monday, 9 October 2023 at 16:42:38 UTC, mw wrote:

use:

import std.conv;

[...]


Damn, sorry, forgot to mention. I cannot use Phobos.


How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?

2023-10-09 Thread rempas via Digitalmars-d-learn

Let's see the following example:

```d
import std.stdio;

static foreach(i; 0 .. 10) {
  mixin(create_fn!(i.stringof));
}

enum create_fn(string num) = `
  void function_`~ num ~`() { writeln("Hello from function `~ num 
~`!"); }

`;

void main() {
  function10();
}
```

I'm trying to create a series of function. There will be ten of 
them, and they will be called `function_0`, `function_1`, etc. 
However, in my example, "stringof" returns the character "i" 
itself and turns that into a string instead of getting its actual 
value (number).


Any ideas how I can achieve what I'm trying to achieve?


Re: malloc error when trying to assign the returned pointer to a struct field

2023-09-09 Thread rempas via Digitalmars-d-learn

On Saturday, 9 September 2023 at 10:54:34 UTC, bachmeier wrote:
Hate to be that guy, but I posted a link to a stackoverflow 
question with the exact error message you were getting, and the 
solution. And I told you I had experienced the same error and 
that question fixed it.


No reason to not says something, always speak you mind my friend!

I did read it and all the replies but the problem is that, I was 
so focused on thinking that something is going wrong with the 
compiler or with libc or something unexpected. For that reason, I 
made the mistake to not see other things that might had gotten 
wrong even tho you literally gave me the answer! That's another 
problem of mine that I am aware and trying to fix (not only when 
it comes to coding but in general) and I do apologize for wasting 
both mine and everyone else's time!


Now that people explained to me, I fully understood what's going 
on and how I made the mistake. Have a great day my friend and I 
hope I can repay one day! ;)


Re: malloc error when trying to assign the returned pointer to a struct field

2023-09-09 Thread rempas via Digitalmars-d-learn

On Saturday, 9 September 2023 at 09:56:59 UTC, H. S. Teoh wrote:
libc doesn't know what you intended. All it knows is that you 
asked it for 20 bytes (even though you actually needed 40), 
then later on its internal structures are corrupted (because 
you thought you got 40 bytes; storing data past the 20 bytes 
overwrote some of malloc's internal data -- this is the buffer 
overrun / buffer overflow I referred to). So it aborts the 
program instead of continuing to run in a compromised state.



T


Thank you! I fully realize now what's the problem! And that was 
indeed a very sneaky problem. The good news is that I'm mostly 
done with these memory structures and functions so I will 
probably take a while since I find something similar.


I'm lucky there are people smarter, more experience that are 
willing to help. Bless you all and have a great day!


Re: malloc error when trying to assign the returned pointer to a struct field

2023-09-09 Thread rempas via Digitalmars-d-learn
On Saturday, 9 September 2023 at 09:47:14 UTC, Steven 
Schveighoffer wrote:

You are focusing on the wrong problem.

You asked for size bytes, and malloc gave you size bytes. It 
doesn't "know" anything special.


Then you proceeded at some point to write *past* the size 
bytes. What did you overwrite? Probably some internal malloc 
implementation structure. Then it later noticed "hey, this 
structure doesn't make sense, I'm going to report it to the 
user!" That's why you see the message.


Memory problems are very difficult to find, and typically an 
error is triggered far away from the source, in seemingly 
unrelated code. This is why whenever I see an error that smells 
like memory corruption, I stop all other work and find it. 
Memory errors can come and go based on random chance or how the 
compiler lays out functions. So having it "just go away" isn't 
enough. Very very infrequently, this happens because of a 
codegen issue, but most of the time it's pilot error.


-Steve


I understand! Thank you for the valuable information. I do have 
lots of things to learn it seems. But that means that I also 
won't get bored anytime soon ;)


Re: malloc error when trying to assign the returned pointer to a struct field

2023-09-09 Thread rempas via Digitalmars-d-learn
On Saturday, 9 September 2023 at 09:04:18 UTC, Steven 
Schveighoffer wrote:
This is not ideal. Why? Because 99% of the time, a poster has 
come here with a problem they don't know how to solve, and have 
focused in on where they *think* the problem is. However, the 
problem isn't there. But us reading the description can only 
see what the poster sees, and either don't see a problem ("I'm 
just as confused as you are!") or know there is more to the 
story.


Not only that, but frequently not-complete code is... not 
complete. And people tend to focus on problems they can see 
(e.g. where is that `_len` defined?), frustrating the poster 
with "trivial" problems that are solved "in the real code".


Inevitably, there is a subsequent post with the real code, and 
that contains the problem.


The best thing to post is a minimally reproducing example. The 
next best thing is a link to a complex reproducing example. 
Which you have done later (I will take a look). I just wanted 
to point this out because it's a frequent problem on these 
forums.




Yeah... I got my lesson! Tbh, I wanted to avoid posting my source 
as much as possible because I do have this "perfectionist" 
mindset (which I am aware is bad and trying to get rid of, and 
have already done progress) and I want the source to sound as 
"professional" as possible as I take serious my project and have 
hopes for it! But yeah, NEVER again!


Here, you have allocated `size` bytes for the array. Is this 
what is intended? Your comments suggest otherwise! If 
`T.sizeof` is 2 or more, then you still only allocate e.g. 20 
bytes for a `_cap` of 20. but an array of 20 T's would require 
40 bytes.


-Steve


Bingo! You and Brad found out! And like I said to him, it's funny 
that I had a previous function that just allocates memory and I 
removed it and then created that one and in that one, I forgot 
about that. It's super funny cause I even wrote the comment that 
explains it and my reallocation function (that gets triggered 
when someone wants to expand the collection) has that 
multiplication one it.


Thank you and everyone else for the help! Hope I can at least 
finish and share something that people will enjoy using!


Re: malloc error when trying to assign the returned pointer to a struct field

2023-09-09 Thread rempas via Digitalmars-d-learn

On Saturday, 9 September 2023 at 08:54:14 UTC, Brad Roberts wrote:
I'm pretty sure this is your problem.  You're allocating size 
bytes which is only going to work where sizeof(T) == 1.  
Changing to malloc(size * sizeof(T)) is likely going to work 
better.


Oh man That was it! I had forget about that! Funny enough, 
the reallocation tests I do letter when expanding the vector do 
include that but I had forgot to place it in the new (because I 
had the an old one and it included this) constructor I had made 
that only allocates memory!


Now, if only one could expect how and why "libc" knows that and 
doesn't just care to give me the memory I asked it for? Or it 
could be than D does something additional without telling us? 
Which can explain when this memory is only present when I assign 
the value to the "this._ptr` field!


Hope I don't have other memory related errors until I finish the 
compiler...


How can I thank you


Re: malloc error when trying to assign the returned pointer to a struct field

2023-09-09 Thread rempas via Digitalmars-d-learn

On Friday, 8 September 2023 at 19:48:33 UTC, Basile B. wrote:


My idea was that if you dont have defined a copy constructor 
and if an instance is assigned to another, then that other 
instance share the same pointer, which can cause memory errors.


To eliminate that risk and to detect where default 
post-blitting may happen you can add


```d
@disable this(this);
```

to the struct.


Thank you! I did and I got a bunch of errors! Seeing where they 
are located, it doesn't seem to be in the file and instances that 
give me the error. Something really weird happens.


I'll probably return to my own memory allocated and fix the bugs 
I had there, it will probably take me less time...


Re: malloc error when trying to assign the returned pointer to a struct field

2023-09-09 Thread rempas via Digitalmars-d-learn

On Friday, 8 September 2023 at 19:14:47 UTC, H. S. Teoh wrote:
The error message looks to me like a corruption of the malloc 
heap. These kinds of bugs are very hard to trace, because they 
may go undetected and only show up in specific circumstances, 
so small perturbations of completely unrelated code may make 
the bug appear or disappear -- just because the bug doesn't 
show up when you disable some code does not prove that that's 
where the problem is; it could be that corruption is still 
happening, it just so happens that it goes unnoticed when the 
behaviour of the code changes slightly.


Yep! That's what I guess as well! Tbh, I knew that playing with 
memory and trying to write a system library will be a touch job 
and I'm up for it! But these bugs really burn me out because like 
you said, nobody can truly help because they are so weird...


My guess is that you have a double-free somewhere, or there's a 
buffer overrun. Or maybe some bad interaction with the GC, e.g. 
if you tried to free a pointer from the GC heap. (Note that 
this may not immediately show up; free() could've assumed that 
everything was OK when it has in fact messed up its internal 
data structures; the problem would only show up later on in 
code that's actually unrelated to the real problem.)


I have commented out every `free` at this point just to be sure 
and still the problem remains. I don't know what a "buffer 
overrun" is, I will make my research and I will reply you when I 
try. The GC does not exist as I'm `betterC`.


If I were in your shoes I'd use Valgrind / Memcheck to try to 
find the real cause of the problem.  Chances are, it may have 
nothing to do with the bit of code you quoted at all.  You 
could try to insert extra malloc/free's in various places 
around the code (in places along the code path, but unrelated 
to the problematic code) to see if that changes the behaviour 
of the bug. If it does, your corruption is likely somewhere 
other than the _ptr code you showed.



T


Thanks for the advice! I already used Valgrind before I bother 
you guys but because at this point of development, I didn't cared 
about freeing the memory, "valgrind" points so many errors that 
it isn't useful to help me identify what's wrong.


Re: malloc error when trying to assign the returned pointer to a struct field

2023-09-09 Thread rempas via Digitalmars-d-learn

On Friday, 8 September 2023 at 19:14:47 UTC, H. S. Teoh wrote:


My guess is that you have a double-free somewhere, or there's a 
buffer overrun. Or maybe some bad interaction with the GC, e.g. 
if you tried to free a pointer from the GC heap. (Note that 
this may not immediately show up; free() could've assumed that 
everything was OK when it has in fact messed up its internal 
data structures; the problem would only show up later on in 
code that's actually unrelated to the real problem.)




Wait! I did searched on the web! I cannot find anything about a 
"buffer overrun"! I only find about "buffer overflow".


Re: malloc error when trying to assign the returned pointer to a struct field

2023-09-09 Thread rempas via Digitalmars-d-learn
On Friday, 8 September 2023 at 16:17:15 UTC, Richard (Rikki) 
Andrew Cattermole wrote:


I would strongly suggest that you log all memory sizes that are 
allocated, and double check that you do free.


Also turn on ASAN in ldc.

http://johanengelen.github.io/ldc/2017/12/25/LDC-and-AddressSanitizer.html


Aha! In the search I made about this problem, I've seen a thread 
talking about "sanatizer=address" but only in C. I searched how I 
can use this one on LDC and I wasn't able to find it so, thank 
you!


Unfortunately, I didn't helped because it has the same kind of 
output with [Valgrind](https://valgrind.org/) so it isn't very 
useful in my case...


Re: malloc error when trying to assign the returned pointer to a struct field

2023-09-08 Thread rempas via Digitalmars-d-learn

On Friday, 8 September 2023 at 16:02:36 UTC, Basile B. wrote:


Could this be a problem of copy construction ?


I don't think so. The assertion seems to be violated when 
`malloc` is used. And when I assert the result in the `_ptr` 
field. Really weird...


Re: I don't understand betterC

2023-09-08 Thread rempas via Digitalmars-d-learn

On Monday, 4 September 2023 at 07:39:21 UTC, confused wrote:


So then I guess I'd still like to know how I'm expected to 
store and access an array of characters without the C runtime 
as I tried in my original post.


You are going to allocate memory using the system call of your 
operation system and then you'll use a pointer as you would if 
you had used "malloc".


Is this what you are trying to do?


Re: malloc error when trying to assign the returned pointer to a struct field

2023-09-08 Thread rempas via Digitalmars-d-learn

On Friday, 8 September 2023 at 07:59:37 UTC, rempas wrote:

[I do have ... I do use ldc2 and `betterC`!]


For anyone who is still following, first of all thanks! Second, I 
have bad news and good news!


The bad news is that I tested in an Linux Mint system (mine is an 
Arch Linux) and the it still doesn't work. So unless it's a bug 
in EVERY glibc on Linux, it will take me days to find it at best 
(I can feel the burnout coming!)...


The good news is that I have 
[uploaded](https://codeberg.org/rempas/nemesis) the source code 
and as I have already asked for help for that codebase in the 
past and I'll probably ask in the future, I now have a proper 
codebase to showcase when the "smallest possible example" is not 
enough!


More specifically, look at the showcases 
[Vec](https://codeberg.org/rempas/nemesis/src/branch/dev/source/erebos/structs/vector.d#L44) struct and the [template](https://codeberg.org/rempas/nemesis/src/branch/dev/source/erebos/structs/array.d#L38) that it expands on its body!


The test that fails is for a function called 
[split](https://codeberg.org/rempas/nemesis/src/branch/dev/source/erebos/algorithms/split.d#L6) and it is located [here](https://codeberg.org/rempas/nemesis/src/branch/dev/source/tests/algorithms/test_split.d#L21) (I specifically point to the line that fails inside the test).


Once again, thank you all for the support!


Re: malloc error when trying to assign the returned pointer to a struct field

2023-09-08 Thread rempas via Digitalmars-d-learn
On Friday, 8 September 2023 at 14:40:13 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
No, for this you need ModuleInfo. The order is sequential on 
what it sees first.


Personally I test using full D rather than -betterC.

For dub:

```json
"configurations": [
{
"name": "library",
"targetType": "dynamicLibrary",
"versions": [
"DynamicSideroBase"
],
"buildOptions": [
"betterC"
]
},
{
"name": "static",
"targetType": "staticLibrary",
"buildOptions": [
"betterC"
]
},
{
"name": "unittest"
},
{
"name": "executable",
"targetType": "executable"
}
]
```


Thank you for all the information! I really appreciate it my 
friend!


Re: malloc error when trying to assign the returned pointer to a struct field

2023-09-08 Thread rempas via Digitalmars-d-learn

On Friday, 8 September 2023 at 14:50:17 UTC, Kagamin wrote:


Did you run this example program above? Does it crash?


I didn't as I suppose that it would had no problems as it works 
for you. Either that, or it will be indeed a problem with my 
Glibc.


I did run it now after your reply and it works without any 
problems!


Re: malloc error when trying to assign the returned pointer to a struct field

2023-09-08 Thread rempas via Digitalmars-d-learn
On Friday, 8 September 2023 at 13:34:42 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
In case you didn't know, all you need to get unittests working 
in -betterC is:


```d
foreach (module_; allModules) {
foreach (unitTest; __traits(getUnitTests, 
module_)) {
unitTest();
}
}
```

You'd need to provide allModules somehow, like dub does.

https://github.com/dlang/dub/blob/2ea883833adf085095b07a7dba8250fb3db79a71/source/dub/project.d#L1937


Oh wow!!! How did I missed that? It's either recent (past months) 
or I'm blind, lol!


As I don't remember unittests however, I would like to as. Do 
they have automatic symbol order resolution? Which is, testing 
symbols that other symbol depend on first? Or is it random?


Re: malloc error when trying to assign the returned pointer to a struct field

2023-09-08 Thread rempas via Digitalmars-d-learn

On Friday, 8 September 2023 at 13:05:47 UTC, evilrat wrote:


You run with -unittest compiler flag? Well, that does nothing 
for me with betterc (without it is ok).


I did stupid and unsafe things like malloc(0) and writing out 
of bounds but still no crash, it works fine.


I guess it depends on your libc, tested this on ubuntu 23.04 
with gcc12 install and ldc 1.32.2


```d
import core.stdc.stdlib;
import core.stdc.stdio;

alias u64 = ulong;
alias i64 = long;

struct Vec(T) {
private:
  T* _ptr = null; // The pointer to the data
  u64 _cap = 0;   // Total amount of elements (not bytes) we 
can store

  u64 _len = 0;

public:
  /* Create a vector by just allocating memory for it. The null 
terminator is not set for
 strings as, the vector is considered empty and we should  
first push something to it

 in order to use it! */
  this(i64 size) {
this._len = 0;
this._cap = size;

static if (is(T == char)) { size += 1; } // Additional 
space for the null terminator

this._ptr = cast(T*)malloc(size);
  }

  ref T opIndex(size_t idx) { return _ptr[idx]; }
}

extern(C)
void main()
//unittest
{
enum el = 3;
auto vec = Vec!char(10);
assert(vec._ptr);
vec[el] = 'h';
assert(vec[el] == 'h');
printf("ptr = %p\n", vec._ptr);
printf("vec ptr = %p\n", [el]);
printf("vec local = %p\n", );
printf("vec[%d] = %c\n", el, vec[el]);
foreach (i; 0..vec._cap) {
  printf("-");
}
printf("\n");
foreach (i; 0..vec._cap) {
  printf("%d", vec[i]);
}
printf("\n");
printf("run ok\n");
}
```

ldc2 -betterC -run membug.d

output

```
ptr = 0x55cb701de2a0
vec ptr = 0x55cb701de2a3
vec local = 0x7fffa1542258
vec[3] = h
--
00010400
run ok
```


As D's "uninttest" feature is disabled on BetterC, I have wrote 
my own testing suit (with is very simple). I just said that to 
point out that I'm testing this data structure (along side other 
things) and I cannot find anything wrong.


I have made a search on the web and I found out one thread that 
pointed out that it may be a Glibc error. However, because like I 
said the problem only happens when I assign the returned value to 
the `_ptr` field, I just wanted to post here in case someone has 
a similar experience and if it's a compiler bug in which case, we 
should report it.


I will use a VM to test my code in another environment and I'll 
be back to report!


Re: malloc error when trying to assign the returned pointer to a struct field

2023-09-08 Thread rempas via Digitalmars-d-learn

On Friday, 8 September 2023 at 09:25:59 UTC, Hipreme wrote:


Hello, not completely unrelated to your problem, I have also 
done something like that, and when you're in D, don't use 
simply a pointer and length like that, use the `slice` operator.


See references:

https://tour.dlang.org/tour/en/basics/slices
https://dlang.org/spec/operatoroverloading.html#array-ops


For example, you can make your pointer a lot safer by doing:

```d
size_t length = 5;
int* pointer = cast(int*)malloc(int.sizeof * length); //Don't
int[] mallocArray = (cast(int*)malloc(int.sizeof * 
length))[0..length]; //Do

```

On the second way, you'll get bound checks, thus, making it 
safer. Also, no need to keep track of your length separately 
anymore.


This is good practice in D language and you'll find yourself 
using this instead in the future.


And yes, this works in betterC, it is a simple runtime check, 
completely `@nogc @safe nothrow` and every other kind of thing 
you would want.


Thank you for the reply! Using slices will give me the same 
result (my code has another field that I forgot to mention btw 
and it's `_len` (which holds the length that is used from the 
capacity). However, this will just make the API worse to use so I 
choose to not use slices in this case as using separate fields is 
more convenient.


Re: malloc error when trying to assign the returned pointer to a struct field

2023-09-08 Thread rempas via Digitalmars-d-learn

On Friday, 8 September 2023 at 09:07:12 UTC, evilrat wrote:


Hard to tell from that code but it is quite unlikely there is a 
compiler bug in such simple use case.


I assume you already tried debugging your program, right?


Yep! I have spent days and it's these kinds of bugs that burn me 
off and make me want to give up.


So how about to diagnose a bit more, what if you enforce check 
before malloc that size>0,


In the real code, there is a check! I just removed it from this 
example to make the code more clear.


and second - from that example it is unclear how you are using 
that struct, so maybe add else statement static assert to see 
if it is misused somewhere else in your codebase?


That's interesting, I wasn't able to find something else! The bug 
happens when I run the testing suit and well... the tests before 
pass so I cannot find anything that goes wrong except for the 
fact that I do not free the memory that is allocated (on purpose).


But still, why would the bug be there when I assign the `_ptr` on 
the field and it won't happen if I don't assign it and just use a 
regular local variable instead (and don't assign anything to the 
`_ptr` field)?


Also this example doesn't have len field, depending on how you 
use with regard to cap this could be a source of problems too.


Oh right, I forgot about that! The `_len` field normally exists 
and it's it's also an unsigned 64-bit (u64) number! Yeah, the 
code is a little bit changed from the original to make it more 
simple for you guys...


malloc error when trying to assign the returned pointer to a struct field

2023-09-08 Thread rempas via Digitalmars-d-learn

I do have the following struct:

```d
struct Vec(T) {
private:
  T* _ptr = null; // The pointer to the data
  u64 _cap = 0;   // Total amount of elements (not bytes) we can 
store


public:
  /* Create a vector by just allocating memory for it. The null 
terminator is not set for
 strings as, the vector is considered empty and we should  
first push something to it

 in order to use it! */
  this(i64 size) {
this._len = 0;
this._cap = size;

static if (is(T == char)) { size += 1; } // Additional space 
for the null terminator

this._ptr = cast(T*)malloc(size);
  }
}
```

That's some minimal code that I do have just to showcase it. So, 
some times, this work will works, some others, it will give me 
the following error:


`Fatal glibc error: malloc.c:2594 (sysmalloc): assertion failed: 
(old_top == initial_top (av) && old_size == 0) || ((unsigned 
long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned 
long) old_end & (pagesize - 1)) == 0)`


The problem seems to happen when the pointer that is returned 
from `malloc` is assigned to the `_ptr` field. If I just assign 
it to a variable and don't assign anything to `_ptr`, it will 
work!


Is there any possible that there is a compiler bug? I do use ldc2 
and `betterC`!


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

2023-06-19 Thread rempas via Digitalmars-d-learn

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


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


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


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

2023-06-19 Thread rempas via Digitalmars-d-learn

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


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

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


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


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

2023-06-19 Thread rempas via Digitalmars-d-learn

On Sunday, 18 June 2023 at 20:24:10 UTC, Cecil Ward wrote:


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


Other than the execution runtime, one other very important 
problem with DMD that wasn't refered is that is only support x86 
and x86_64. LDC and GDC support LLVM's and GCC's architectures 
respectively.


Re: need `this` for `this` of type `ref @safe Test(string reg_arg)

2023-06-18 Thread rempas via Digitalmars-d-learn

On Sunday, 18 June 2023 at 19:22:45 UTC, Paul Backus wrote:


No, there is no way to pass template arguments to a constructor 
without using `__ctor`.


My recommendation is to use a free function or a `static` 
method instead. For example:


```d
import std.stdio;

struct Test {}

Test makeTest(string type = "def")(string reg_arg)
{
writeln("reg_arg: ", reg_arg);
return Test();
}

void main()
{
auto test = makeTest!"non_def"("Hello");
}
```


Thank you! This will make me change the design of my API a little 
bit but it will do ;)


Re: need `this` for `this` of type `ref @safe Test(string reg_arg)

2023-06-18 Thread rempas via Digitalmars-d-learn

On Sunday, 18 June 2023 at 18:17:16 UTC, Paul Backus wrote:


`__ctor` doesn't create a new object, it initializes an 
existing object. You need to create the object first, then call 
`__ctor` on it:


```d
void main() {
  Test test;
  test.__ctor!("non_def")("Hello");
}
```


Thank you! Do you know any other way to do it without using 
"__ctor".


I'm not sure if it was clear that it's not that I specifically 
want to do it with "__ctor" so I'm making it clear just to be 
sure.


need `this` for `this` of type `ref @safe Test(string reg_arg)

2023-06-18 Thread rempas via Digitalmars-d-learn
Ok, so I'm having a struct that has a constructor that takes a 
template parameter. I suppose this question could also be named 
`how to initialize constructors with template parameters` but 
whatever! The funny thing is, I think that I may have already 
found how to do it in the past but I forgot... This time, I'm 
going to add the code in a big module in my project so I'm not 
going to have it as a reference and I won't forget it.


Here is a small sample code:

```d
import std.stdio;

struct Test {
  this(string type = "def")(string reg_arg) {
writeln("reg_arg: ", reg_arg);
  }
}

void main() {
  auto test = Test.__ctor!("non_def")("Hello");
}
```

And the error I get: `test.d(10): Error: need `this` for `this` 
of type `ref @safe Test(string reg_arg)`


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

2023-06-18 Thread rempas via Digitalmars-d-learn

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


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


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

2023-06-18 Thread rempas via Digitalmars-d-learn

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


I do wonder why no-one have linked the [Modules and 
libraries](https://ddili.org/ders/d.en/modules.html) section in 
the [Programming in D](https://ddili.org/ders/d.en/index.html) 
book! The book is outdated in some things (and this isn't with 
logic, I have found one of these cases myself) but for most 
things, it will be ok!


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

2023-06-02 Thread rempas via Digitalmars-d-learn

On Friday, 2 June 2023 at 11:27:31 UTC, Andrew wrote:


Others can correct me if I'm wrong, but I don't think that it 
is a priority for D to be specially compatible with makefiles 
in any way beyond the whole separation of compilation and 
linking.


If he was talking about using GNU Make as a build system for D, 
then you are right! We have [dub](https://dub.pm/index.html) for 
that exact reason!


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

2023-06-02 Thread rempas via Digitalmars-d-learn

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


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


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


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

2023-06-02 Thread rempas via Digitalmars-d-learn

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


I do wonder why no-one have linked the [Modules and 
libraries](https://ddili.org/ders/d.en/modules.html) section in 
the [Programming in D](https://ddili.org/ders/d.en/index.html) 
book! The book is outdated in some things (and this isn't with 
logic, I have found one of these cases myself) but for most 
things, it will be ok!


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

2023-06-02 Thread rempas via Digitalmars-d-learn

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


I do wonder why no-one have linked the [Modules and 
libraries](https://ddili.org/ders/d.en/modules.html) section in 
the [Programming in D](https://ddili.org/ders/d.en/index.html) 
book! The book is outdated in some things (and this isn't with 
logic, I have found one of these cases myself) but for most 
things, it will be ok!


Re: How can a function pointer required to be extern(C)?

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

On Wednesday, 12 April 2023 at 21:00:04 UTC, John Chapman wrote:


You can also express it like this:

```d
extern(C) alias FuncPtr = void* function(void*);
```


Thank you! This is how I was planning to do anyway because other 
that the fact that I like the syntax of that a little bit more, 
this code will be part of the library so there will not be any 
function to take its type so I cannot do this the other away even 
if I wanted. Have an amazing day my friend!


Re: How can a function pointer required to be extern(C)?

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

On Wednesday, 12 April 2023 at 20:36:59 UTC, H. S. Teoh wrote:


IMO this is a bug either in D's syntax or in the parser.  I'd 
file an enhancement request.


In the meantime, you can use alias as a workaround:


---snip---
extern(C) void* abc(void*) {return null;}

alias FuncPtr = typeof();
pragma(msg, typeof(abc));
pragma(msg, typeof());

//void wrapper(extern(C) void* function(void*) callback) {} // 
NG

void wrapper(FuncPtr callback) {} // OK

pragma(msg, typeof(wrapper));
---snip---


T


Thank you! As long as there is a way to do it with aliases, I 
don't think that there is a reason to even bother the developers. 
I mean, it will just save me 1 line of code in my whole project 
(because I don't think I'll use this even again somewhere else) 
so I don't think it's worth it. Thank you for your help. Best 
thing with Dlang is the community ;) I wish you to have an 
amazing day!




How can a function pointer required to be extern(C)?

2023-04-12 Thread rempas via Digitalmars-d-learn
Sorry if the title doesn't make any sense, let me explain. So, I 
do have the following code that does not compile:


```d
import core.sys.posix.pthread; /* The library */

struct Thread {
private:
  pthread_t thread_id;

public:
  this(void* function(void*) func, void* arg = null, scope 
const(pthread_attr_t*) attr = null) {

pthread_create(_id, attr, func, arg);
  }

  @property:
pthread_t id() { return this.thread_id; }
}

```

Yes, I'm trying to "encapsulate" the Pthread (POSIX threads) API. 
Normally, the function pointer that is passed to "pthread_create" 
must be "extern(C)" and this is the complaining that the compile 
does. So, I'm thinking to replace the constructor to this:


```d
this(extern(C) void* function(void*) func, void* arg = null,
 scope const(pthread_attr_t*) attr = null)
{ pthread_create(_id, attr, func, arg); }
```

I just added "extern(C)" before the type. This is how it looks in 
the error message so it must work right? Well... it doesn't. And 
here I am wondering why. Any ideas?


Re: @nogc and Phobos

2023-04-12 Thread rempas via Digitalmars-d-learn

On Tuesday, 14 March 2023 at 20:40:39 UTC, bomat wrote:


Sounds intriguing. Anything I can look at yet? Or still all top 
secret? :)


Oh, amazing! I let you on waiting for almost a month and I 
wouldn't had see it if I didn't came to post another question.


I'm so so sorry for the waiting, I will not even use an excuse. 
So, if you are willing to make an account on 
[Codeberg](https://codeberg.org/), the repository is private but 
after making the account, follow 
[me](https://codeberg.org/rempas) and I will give you access! 
Tho, you may read something cringe! Be prepared, lol!


Re: @nogc and Phobos

2023-03-11 Thread rempas via Digitalmars-d-learn

On Saturday, 11 March 2023 at 16:21:40 UTC, bomat wrote:
first: I didn't want to sound aggressive or like I was trying 
to bash D, sorry if it came across like that.


Oh don't worry! People have openly criticized (and still doing) 
the language before. It's nothing to worry, criticism help us 
becoming better. But I didn't got these vibes from your post to 
begin with ;)


Second: I find it super interesting what you say about you not 
actually liking Phobos and the built-in structures of D.
Although I have not seen very much yet, I think I have to agree 
to that.


Well, when I first started using D, coding on it was very very 
easy and enjoyable. I didn't had to think a lot and things "just 
worked"™️. Then, things chanced... Haven't made anything at this 
point except for some small programs. Now, I'm making my first 
"big" project and it's a compiler for my new language. So 
ironically enough, that will be my first and final project in D.


Although I come from a C++ background, I'm not exactly a fanboy 
of that language (you can probably tell, otherwise I wouldn't 
be here).


My dear, if anyone would tell me that they are a fanboy of this 
mess called C++, I wouldn't believe them...


But after hearing praise for D for being a cleaner and better 
version of C/C++, I am a bit disappointed so far, tbh.


Well, of course we are a little bit disappointed when things are 
not tuned EXACTLY how we want them. There are things that D 
OBJECTIVELY does just wrong and they could have been much better. 
However, it's still much much much much better than C and even 
C++. And that's not a lie and I'm not a "fanboy". I tried to use 
them both for my project and D is straight up day and night with 
these two. If D has 3-4 annoying things, C and C++ have 10! And 
again, this is with `betterC` in mind. I don't even use the whole 
power of D. But again, nothing is perfect unless you build it, 
hence why I making my own that will include a lot of great 
features from D as it also objectively handles some things with a 
good way.


but I think it repeats too many old sins, like implicit type 
conversions, the `for` loop syntax (although I guess one 
wouldn't need it that often because of `foreach`),


Does it have "implicit" type conversion? I didn't even knew, lol! 
The `foreach` will cover your needs like you said but ironically 
enough, I like and use the original `for` loop.



the `switch` `case` fallthrough,


I have nothing to say for that, I have said it before and lots of 
others have as well.


and the cancerous `const` (as far as I can tell, `immutable` is 
an even worse flavor of it).


Yeah, another thing I'll change in my language. The way 
immutability is treated is so so bad for so many reasons.


Despite all of that, I can't argue with the fact that it may 
still be the best compiled language currently around. Sadly 
enough, though, imo that isn't that much of a compliment. :)


Well, the competition is pretty weak, yeah. Tho based on my 
experience, it doesn't worth to waste your time on anything else 
at this point. We can speak about trying a different language 
after mine is out ;)





Re: How can I get the scalar type of a pointer to pointer (and in even deeper levels)

2023-03-11 Thread rempas via Digitalmars-d-learn

On Saturday, 11 March 2023 at 13:37:26 UTC, ag0aep6g wrote:

On 11.03.23 14:22, rempas wrote:

On Saturday, 11 March 2023 at 12:59:59 UTC, ag0aep6g wrote:


alias Foo(T : U*, U) = Foo!U;
alias Foo(T) = T;
static assert(is(Foo!(int*) == int));
static assert(is(Foo!(int**) == int));
static assert(is(Foo!(int***) == int));
static assert(is(Foo!(int) == int));


Wait, but "Foo" is defined twice and it doesn't let me 
compile...


You're doing something wrong then.

Don't put the Foo declarations in a function or unittest.


Oh, so it tries to re-define them if I put them inside a 
function! Thank you brother, works great! Have a great day!


Re: How can I get the scalar type of a pointer to pointer (and in even deeper levels)

2023-03-11 Thread rempas via Digitalmars-d-learn

On Saturday, 11 March 2023 at 12:59:59 UTC, ag0aep6g wrote:


alias Foo(T : U*, U) = Foo!U;
alias Foo(T) = T;
static assert(is(Foo!(int*) == int));
static assert(is(Foo!(int**) == int));
static assert(is(Foo!(int***) == int));
static assert(is(Foo!(int) == int));


Wait, but "Foo" is defined twice and it doesn't let me compile...


Re: @nogc and Phobos

2023-03-11 Thread rempas via Digitalmars-d-learn

On Saturday, 11 March 2023 at 12:04:25 UTC, bomat wrote:

Hello! First of all, let's start by making clear of what `@nogc` 
means. It it an attribute that is used one function signatures 
and it annotates that the garbage collector will not be used 
inside this function. However, in the scenario that we have 
`func1` that is annotated with `@nogc` and `func2` that is called 
by `func1`, I don't know if `func2` needs to be annotated with 
`@nogc` as well. This is not been said inside the SPEC (or at 
least, I didn't found it with the quick search I did) so someone 
could confirm or deny this if they know.


It works fairly well so far, just one problem: Dear ImGui is 
obviously `@nogc`, and I noticed that it doesn't mix with 
standard library functions.


Is it what people say "100% `@nogc`" which means that it doesn't 
use the garbage collector or does it use 
[betterC](https://dlang.org/spec/betterc.html)?



So my question is:
Is Phobos essentially incompatible to `@nogc`?


Look [here](https://dlang.org/spec/function.html#nogc-functions) 
about the features that cannot be used with `@nogc`. Keep in mind 
that using `@nogc` in your project, will still have it link with 
Phobos and D's runtime library. `BetterC` is what disables the 
garbage collector completely (so no need for `@nogc`) but also 
doesn't make your binary/library link with D's runtime and 
Phobos. But if you don't use this mode, you will be able to link 
with the standard library and use the functions that do not use 
the garbage collector.


Or is there a trick for mixing GC code with non-GC code that I 
don't know?


For what I know, you can combine both methods by using the GC and 
also mannually allocating memory with libc's "malloc" (or of 
course your own allocator) but you'll probably have to look into 
some documentation on how to combine them without any sneaky 
bugs. However, you will probably not have to do anything 
"special" to make it work. As I never did it, maybe someone else 
could help on that one.




I'm assuming the second, for if the first was true I'd say that 
D would be pretty much useless when combined with non-D libs...


Even if the first was the case (which again, only things that 
need the GC will not be able to be used), D is far from been 
"useless". You can use `betterC` and use C's libraries. 
Personally, that's what I'm doing anyway. Even if there was no 
garbage collector and a runtime, I still don't like Phobos and 
the built-in structures of D. It is still far far better than 
pretty much any other (compiled) language out there in case of 
usability so it's not useless at all even if you cannot use the 
standard library!




How can I get the scalar type of a pointer to pointer (and in even deeper levels)

2023-03-11 Thread rempas via Digitalmars-d-learn

Let's see the following code:

```d
void test_fn(T)(T val) {
  pragma(msg, "The type of the pointer is: " ~ 
typeof(*val).stringof);

}

extern (C) void main() {
  int* int_ptr = cast(int*)0x1037;
  char* char_ptr = cast(char*)0x1037;

  test_fn(int_ptr);
  test_fn(char_ptr);
}
```

This function takes a templates argument that can be any 
(pointer) type and shows the scalar type of the pointer (at 
compile time). I'm using the "typeof" operator and I'm 
referencing the pointer so I can get the scalar type. This will 
work great for single pointer values but what about pointers to 
pointers like: `int`? Is there a way that I would be able to 
always get the scalar type of a pointer regardless of how many 
levels it is? As always, I'm searching for a solution that will 
work in `BetterC`.


Re: Is there a way to get the name of the current function?

2023-03-07 Thread rempas via Digitalmars-d-learn

On Tuesday, 7 March 2023 at 22:28:41 UTC, ryuukk_ wrote:



```
import std.stdio;
void main()
{
writeln("file:", __FILE__);
writeln("function is: ", __FUNCTION__);
writeln("function is: ", __PRETTY_FUNCTION__ );
}

$ dmd -run tester.d
file:tester.d
function is: tester.main
function is: void tester.main()
```

You can even get the calling function name:

```
import std.stdio;
void main()
{
log("hello");
}


void log(string msg, string file = __FILE__, int line = 
__LINE__, string fn = __PRETTY_FUNCTION__)

{
writeln(file,":",line,"|", fn,"|> ", msg);
}
```

https://dlang.org/spec/expression.html#specialkeywords


Thanks a lot for the detailed examples! Have an amazing day!


Re: Is there a way to get the name of the current function?

2023-03-07 Thread rempas via Digitalmars-d-learn

On Tuesday, 7 March 2023 at 22:19:22 UTC, JG wrote:


Yes, see here: 
https://dlang.org/spec/expression.html#specialkeywords


OMG, so that's when they are located! I was trying to search the 
spec and find them in different pages but had no luck! Thanks a 
lot for the help, have a great day!


Is there a way to get the name of the current function?

2023-03-07 Thread rempas via Digitalmars-d-learn

For example, in the given code:

```d
void my_function() {
  import std.stdio;

  writeln("The name of the function is: ", 
);

}
```

Is there something to put in the place of 
`` to get the name of the function?


Re: How would the equivalent C type be in D?

2023-03-07 Thread rempas via Digitalmars-d-learn

On Tuesday, 7 March 2023 at 09:05:45 UTC, FeepingCreature wrote:


Yay!

Yes, that is a bit weird. First of all, the actual signal is 11

[...]


Thank you for the info!


Re: How would the equivalent C type be in D?

2023-03-01 Thread rempas via Digitalmars-d-learn

On Wednesday, 1 March 2023 at 08:26:07 UTC, FeepingCreature wrote:


11 is SIGSEGV. A segfault, or access violation, happens when 
you try to access unallocated memory. In this case, let me 
annotate your code so it's easier to see what's happening:


```d
// null is the default value for a pointer
uint* value = null;
// because `value` is null, the first index also lies at null.
assert([0] is null);
// So we try to store screen.black_pixel at memory address 
null, which is unallocated.

value[0] = screen.black_pixel;
xcb_create_gc(connection, black, win, mask, value);
```

As there is no memory segment allocated at address null, the 
CPU indicates a segmentation fault, which terminates the 
program.


So yes, `xcb_create_gc` wants a `uint*` parameter, but not just 
any `uint*` will do: it has to point to valid memory. Going 
back to the first snippet, what's happening here is that in C, 
arrays implicitly convert to pointers, because C doesn't have a 
notion of array types as distinct from pointer types. So you 
can have a variable declared as `uint[1]`, but pass it to a 
parameter that expects `uint*`, and the value that is passed 
will just be the address of the first field of the array. 
However, even in C, if you try to define `value` as `uint*`, it 
will segfault in the same way. Instead, in D, you need to tell 
the compiler to define an array of size 1, and then pass a 
pointer to the array's first member explicitly:


```d
uint32_t[1] value;
value[0] = screen.black_pixel;
// this is what C does under the hood
xcb_create_gc(connection, black, win, mask, [0]);
```

Or shorter, but with the same effect:

```d
uint32_t[1] value;
value[0] = screen.black_pixel;
xcb_create_gc(connection, black, win, mask, value.ptr);
```


Thank you! You are amazing for explaining it! I was so focused on 
thinking that I'm doing something wrong with the type that I 
didn't noticed that the pointers, points to nowhere so the 
function obviously has nowhere to write to. Like... OMG! And I 
want to make a fully fledged compiler when making stupid mistakes 
like that. Btw, When I executed the program, I got "Error Program 
exited with code -11". You said that the code was "11". What 
about that dash? If it is not a "minus" and it's just the dash 
symbol, then what's the idea?


How would the equivalent C type be in D?

2023-03-01 Thread rempas via Digitalmars-d-learn
I'm looking into 
[this](https://www.x.org/releases/X11R7.7/doc/libxcb/tutorial/index.html) tutorial to learn XCB and I'm trying to write the code in D with betterC. In the section 9.1 (sorry, I cannot give a section link, the article does not give us this ability), I'm facing a problem and my program exits with the exit code: "-11". I suspect that this happens because I haven't translated the following code the right way:


```d
uint32_t value[1];
value[0] = screen.black_pixel;
xcb_create_gc(connection, black, win, mask, value);
```

I originally tried to translate this as:

```d
uint[1] value;
value[0] = screen.black_pixel;
xcb_create_gc(connection, black, win, mask, value);
```

But then, when I tried to compile the program, I got the 
following error:


```
Error: function `headers.xcb_create_gc(xcb_connection_t* c, uint 
cid, uint drawable, uint value_mask, const(void)* value_list)` is 
not callable using argument types `(xcb_connection_t*, uint, 
uint, uint, uint[1])`
src/draw.d(18,16):cannot pass argument `value` of type 
`uint[1]` to parameter `const(void)* value_list`

```

So I thought of doing the following:

```d
uint* value;
value[0] = screen.black_pixel;
xcb_create_gc(connection, black, win, mask, value);
```

Now the program complies but I get the "-11" exit code. Another 
thing I thought (which is probably the same thing under the hood 
but done a different way):


```d
const(void)* value;
(cast(ubyte*)value)[0] = screen.black_pixel;
xcb_create_gc(connection, black, win, mask, value);
```

Same results. Any ideas?



Re: How ptr arithmitic works??? It doesn't make any sense....

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

On Monday, 5 December 2022 at 22:21:06 UTC, Salih Dincer wrote:
Yeah, there is such a thing!  I'm sure you'll all like this 
example:


[...]


Great example! Thank you my friend!


Re: How ptr arithmitic works??? It doesn't make any sense....

2022-12-05 Thread rempas via Digitalmars-d-learn

On Monday, 5 December 2022 at 18:01:47 UTC, ag0aep6g wrote:


You can use bracket notation with pointers. You just need to 
move your closing parenthesis a bit.


Assuming that `ptr` is a `void*`, these are all equivalent:

```d
(cast(int*) ptr)[i] = whatever;
*((cast(int*) ptr) + i) = whatever;
*(cast(int*) (ptr + i * int.sizeof)) = whatever;
```


Oh, wow! That's sure interesting! Thanks a lot!


Re: How ptr arithmitic works??? It doesn't make any sense....

2022-12-05 Thread rempas via Digitalmars-d-learn

On Monday, 5 December 2022 at 08:21:44 UTC, bauss wrote:


Because it's much easier to work with.

Ex. if you have an array of 4 signed 32 bit integers that 
you're pointing to then you can simply just increment the 
pointer by 1.


If it was raw bytes then you'd have to increment the pointer by 
4 to move to the next element.


This is counter-intuitive if you're moving to the next element 
in a loop ex.


This is how you'd do it idiomatically:

```d
foreach (i; 0 .. list.length)
{
(*cast(int*)(ptr + i)) = i;
}
```


Is this `(*cast(int*)(ptr + i)) = i;` or you did a mistake and 
wanted to write: `(*cast(int*)ptr + i) = i;`? Cause like we said 
before, the first operand must be a cast to the type for this to 
work right.



Compared to:

```d

foreach (i; 0 .. list.length)
{
(*cast(int*)(ptr + (i * 4))) = i;
}
```


Got it! I guess they could also just allow us to use bracket 
notation to do the same thing. So something like:


```d
foreach (i; 0 .. list.length) {
  (cast(int*)ptr[i]) = i;
}
```

This is what happens with arrays anyways. And arrays ARE pointers 
to a contiguous memory block anyways so they could do the same 
with regular pointers. The example also looks more readable.


Re: How ptr arithmitic works??? It doesn't make any sense....

2022-12-05 Thread rempas via Digitalmars-d-learn

On Sunday, 4 December 2022 at 19:00:15 UTC, H. S. Teoh wrote:
This is true only if you're talking about pointers in the sense 
of pointers in assembly language.  Languages like C and D add 
another layer of abstraction over this.




Another thing with pointers is that it doesn't have "types".


This is where you went wrong.  In assembly language, yes, a 
pointer value is just a number, and there's no type associated 
with it. However, experience has shown that manipulating 
pointers at this raw, untyped level is extremely error-prone.  
Therefore, in languages like C or D, a pointer *does* have a 
type.  It's a way of preventing the programmer from making 
silly mistakes, by associating a type (at compile-time only, of 
course) to the pointer value.  It's a way of keeping track that 
address 1234 points to a short, and not to a float, for 
example.  At the assembly level, of course, this type 
information is erased, and the pointers are just integer 
addresses.  However, at compile-type, this type exists to 
prevent, or at least warn, the programmer from treating the 
value at the pointed-to address as the wrong type.  This is not 
only because of data sizes, but the interpretation of data.  A 
32-bit value interpreted as an int is completely different from 
a 32-bit value interpreted as a float, for example.  You 
wouldn't want to perform integer arithmetic on something that's 
supposed to be a float; the result would be garbage.


In addition, although in theory memory is byte-addressable, 
many architectures impose alignment restrictions on values 
larger than a byte. For example, the CPU may require that 
32-bit values (ints or floats) must be aligned to an address 
that's a multiple of 4 bytes.  If you add 1 to an int* address 
and try to access the result, it may cause performance issues 
(the CPU may have to load 2 32-bit values and reassemble parts 
of them to form the misaligned 32-bit value) or a fault (the 
CPU may refuse to load a non-aligned address), which could be a 
silent failure or may cause your program to be forcefully 
terminated. Therefore, typed pointers like short* and int* may 
not be entirely an artifact that only exists in the compiler; 
it may not actually be legal to add a non-aligned value to an 
int*, depending on the hardware you're running on.


Because of this, C and D implement pointer arithmetic in terms 
of the underlying value type. I.e., adding 1 to a char* will 
add 1 to the underlying address, but adding 1 to an int* will 
add int.sizeof to the underlying address instead of 1. I.e.:


int[2] x;
int* p = [0]; // let's say this is address 1234
p++;// p is now 1238, *not* 1235 (int.sizeof == 4)

As a consequence, when you cast a raw pointer value to a typed 
pointer, you are responsible to respect any underlying 
alignment requirements that the machine may have. Casting a 
non-aligned address like 1235 to a possibly-aligned pointer 
like int* may cause problems if you're not careful.  Also, the 
value type of the pointer *does* matter; you will get different 
results depending on the size of the type and any alignment 
requirements it may have.  Pointer arithmetic involving T* 
operate in units of T.sizeof, *not* in terms of the raw pointer 
value.



T


Wow! Seriously, thanks a lot for this detailed explanation! I 
want to write a compiler and this type of explanations that not 
only give me the answer but explain me in detail why something 
happens are a gift for me! I wish I could meet you in person and 
buy you a coffee. Maybe one day, you never know! Thanks a lot and 
have an amazing day!


Re: How ptr arithmitic works??? It doesn't make any sense....

2022-12-04 Thread rempas via Digitalmars-d-learn

On Sunday, 4 December 2022 at 17:27:39 UTC, Nick Treleaven wrote:

On Sunday, 4 December 2022 at 16:33:35 UTC, rempas wrote:

(MemoryBlock.sizeof is 16 on my 64-bit system).

The above adds 16 bytes to ptr.

The above adds 16 * MemoryBlock.sizeof bytes (16 * 16) to ptr, 
because ptr is cast first. Should be `+ 1` to be equivalent.


https://dlang.org/spec/expression.html#pointer_arithmetic

"the resulting value is the pointer plus (or minus) the second 
operand **multiplied by the size of the type pointed to by the 
first operand**."


Thanks! This explains it. And I have tried and I can only use "+" 
or "-" with a pointer so it explains it.





char* return_address_wrong() {
  MemoryBlock* local_ptr = cast(MemoryBlock*)ptr;
  return cast(char*)(local_ptr + MemoryBlock.sizeof); // 
Casted the whole expression. BUT GOT THE WRONG VALUE Why???

}


Because you are adding to a pointer that points to a 16-byte 
block, rather than a void* which points to a single byte.



char* return_address_right() {
  MemoryBlock* local_ptr = cast(MemoryBlock*)ptr;
  return cast(char*)local_ptr + MemoryBlock.sizeof; // Now I 
first casted the `local_ptr` variable and then added the 
number but this time this gave me the right value

}


The casted pointer points to a single byte.


I think I get it! The first part about the arithmetic explains it 
all well. I was also able to fix my program. They way I see it, 
you return from a function by first casting the first operand and 
when you want to get a variable (or pass one to a function), you 
cast the whole expression. At least that's how it worked with my 
program.





Re: How ptr arithmitic works??? It doesn't make any sense....

2022-12-04 Thread rempas via Digitalmars-d-learn

On Sunday, 4 December 2022 at 16:40:17 UTC, ag0aep6g wrote:


Not quite. Adding 10 to a T* means adding 10 * T.sizeof.


Oh! I thought it was addition. Is there a specific reasoning for 
that if you are aware of?


How ptr arithmitic works??? It doesn't make any sense....

2022-12-04 Thread rempas via Digitalmars-d-learn
First a little bit of theory. A pointer just points to a memory 
address which is a number. So when I add "10" to this pointer, it 
will point ten bytes after the place it was pointing to, right? 
Another thing with pointers is that it doesn't have "types". A 
pointer always just points to a location so types are created for 
the compiler so we can catch bugs when pointing to places and 
trying to manipulate the bytes to a size we probably wouldn't 
want to. For example: if you have allocated 4 bytes and then you 
try to point to it with a type of "short" for example, then you 
could only manipulate 2 of these 4 bytes but you probably 
wouldn't and you did something wrong so we do have types and the 
compiler requires explicit pointer type casting (in contrast to 
C) so it can protect you from these bugs.


This type-casting brings some problem however. So, I played 
around it and I figured it out than to get the right location you 
expect when returning from a function, you need to do the math 
and then cast the whole expression (so the result) and return 
that. If you only cast the first value (that is of the different 
type) an then do that addition (or whatever expression you want), 
it will return a wrong address. But WAIT!!! This doesn't work in 
a different example. And I'm braking my head to understand why 
and I thought about asking if anyone can help and explain to me 
why. Btw, all the testing was made with `ldc` in the `BetterC` 
"mode". Code:


```d
import core.stdc.stdio;
import core.stdc.stdlib;

struct MemoryBlock {
  char* ptr;
  ulong length;
}

void* ptr = cast(void*)0x7a7;

void* right() {
  return cast(MemoryBlock*)(ptr + MemoryBlock.sizeof); // Cast 
the whole expression between paranthesis. Got the right value!

}

void* wrong() {
  return cast(MemoryBlock*)ptr + MemoryBlock.sizeof; // First 
cast the `ptr` variable and then add the number. Got a wronge 
value...

}

char* return_address_wrong() {
  MemoryBlock* local_ptr = cast(MemoryBlock*)ptr;
  return cast(char*)(local_ptr + MemoryBlock.sizeof); // Casted 
the whole expression. BUT GOT THE WRONG VALUE Why???

}

char* return_address_right() {
  MemoryBlock* local_ptr = cast(MemoryBlock*)ptr;
  return cast(char*)local_ptr + MemoryBlock.sizeof; // Now I 
first casted the `local_ptr` variable and then added the number 
but this time this gave me the right value

}

extern (C) void main() {
  printf("EXPECTED LOCATION: %p\n", ptr + MemoryBlock.sizeof);
  printf("RIGHT LOCATION: %p\n", right());
  printf("WRONG LOCATION: %p\n", wrong());

  printf("RETURNED ADDRESS (wrong): %p\n", 
return_address_wrong());
  printf("RETURNED ADDRESS (right): %p\n", 
return_address_right());

}
```




Re: How do I initialize a templated constructor?

2022-08-08 Thread rempas via Digitalmars-d-learn
Thank you all for the info! I'll try to find another way to do it 
as it is not possible

to match the exact behavior I want! Have a great day everyone!



Re: How do I initialize a templated constructor?

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

On Monday, 8 August 2022 at 11:03:21 UTC, Dom Disc wrote:


But if you only want to know the type of the parameter, you can 
do this:


```D
struct TestArray(ulong element_n) {
  int[element_n] elements;

  this(type)(type number)
  {
pragma(msg, "The type is: " ~ type.stringof);
  }
}
```


Unfortunately this will not do as well


Re: How do I initialize a templated constructor?

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

On Monday, 8 August 2022 at 08:27:49 UTC, bauss wrote:


Yeah I think the only template argument you can have for 
constructors are `this` which will refer to things like the 
class that inherited the current class etc. not sure what else, 
but you can't really pass anything to it yourself unfortunately.



It's fine, thanks for trying in any case!

But I think if you end up with something where you need 
different constructors with different type arguments then 
you're probably designing your program in a "wrong" way to 
begin with.



Oh, trust me! I didn't designed my program wrong in my case.
At least not the way I see it!


Re: How do I initialize a templated constructor?

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

On Monday, 8 August 2022 at 06:58:42 UTC, bauss wrote:


```
this(string type)(ulong number) {
```

You cannot do this.

Instead your type should look like this:

First let's change it up a little bit.

```
struct TestArray(ulong element_n, string type) {
  int[element_n] elements;

  this(ulong number) {
pragma(msg, "The type is: " ~ typeof(type).stringof);
  }
}
```

Now the above will still not work because you do `typeof(type)` 
which will always yield string because type is as string and 
also the typeof() is not needed in this case and will actually 
yield an error.


If it must be a string then you can do it like this:

```
struct TestArray(ulong element_n, string type) {
  int[element_n] elements;

  this(ulong number) {
mixin("alias T = " ~ type ~ ";");
pragma(msg, "The type is: " ~ T.stringof);
  }
}
```

However the ideal implementation is probably this:

```
struct TestArray(ulong element_n, T) {
  int[element_n] elements;

  this(ulong number) {
pragma(msg, "The type is: " ~ T.stringof);
  }
}
```

To instantiate it you simply do:

```
TestArray!(10, "int") val = TestArray!(10, "int")(100);
```

Or

```
TestArray!(10, int) val = TestArray!(10, int)(100);
```

I will recommend an alias to make it easier:

```
alias IntTestArray = TestArray!(10, int);

...

IntTestArray val = IntTestArray(100);
```


Thank you for all the great info! Unfortunately, while there is 
no problem in this example, this will
not do for my real code as I need to have the argument in the 
constructor. Alternative, I have to

change the design of the program completely


Re: Hacking C code vs D code

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

On Thursday, 4 August 2022 at 23:11:36 UTC, pascal111 wrote:
One of problems faced me in C programming is hacking data with 
C code that some hackers do with C code which make me needs 
more tools to protect my C code, but I don't have good 
resources in my current time, while I noticed that D code is 
more secure than C code by mean it will be more useful to do my 
codes in my current time.


My question is, to which extent D code is secure and helping in 
protect data?


One of the reasons that C is considered an "unsafe" language is 
because

of `libc`. And this is due to three reasons (at least in my view):

1. `libc` is a low level library and as every low level library, 
it allows you
to have a lot of control but you must know what you're doing. 
But even

when you do, humans do make mistakes and we forget things
2. `libc` doesn't have the best design so programmers can really 
mess up

and not even know it
3. `libc` is a limited library (at least after the basic needs) 
so people have to
write their own code. Compared to having a standard library 
who's open-source
and anyone can use, a library that has been written by a 
developer only for
the needs of the current program means that it will always 
reflect the quality
of the developer himself/herself. At the other point, the 
standard library will
be developed by a team of very experienced programmers 
(expect when n00bs
like me design programming languages and libraries...). This 
is important because
these people will do less mistakes and even when they do, the 
community will
try to improve things here and there. Proper testing is 
another thing software
written by very experienced people have. While beginners tend 
to avoid them

like plague...

The third one is probably the biggest reason. D has its own 
library that builds on
top of `libc` and it's called `phobos` (bonus for its amazing 
name!). For that reason,
D is mostly a safer language than C. Of course, D is as low level 
as C and you have the
ability to use low level features and not use `phobos` but only 
`libc` (check about 
[BetterC](https://dlang.org/spec/betterc.html)).
You can also, use pointers, allocate memory manually, do system 
calls (and write inline
assembly in general) and do pretty much whatever you can do in C. 
If you do it, then D
will be as unsafe as C. So it really comes down to the language 
features and the libraries

that are used. Hope that solved your mysteries ;)


Re: CMake and D

2022-08-07 Thread rempas via Digitalmars-d-learn

On Saturday, 6 August 2022 at 18:22:45 UTC, Jan Allersma wrote:


I figured out a strategy to solve te problem:

1) Create a C++ function which will be called in D.
2) Build a static C++ library with CMake and add dependencies 
(In my case: SDL libraries)

3) Create a new project (`dub init`).
4) Add these lines to `dub.json`:

```
"dflags": ["-L-lstdc++"],
"lflags": ["-Lbuild", "-lframework", "-lSDL2"],
```

- `-L-lstdc++` is needed to use standard C++ functions.
- `-Lbuild` is to add the `build` directory a library path 
(this is the directory where my earlier compiled C++ library is 
in).
- `-lframework` is used to link my earlier compiled C++ library 
`libframework.a`.
- And finally `-lSDL2` because that is a dependency used by my 
C++ library.


Now I can add dependencies for my D code as well using `dub 
add`!


Thank you for posting the solution! And you were fast enough to 
find

it yourself before anyone can arrive with the solution ;)

Happy coding my friend!


How do I initialize a templated constructor?

2022-08-07 Thread rempas via Digitalmars-d-learn

In the following struct (as an example, not real code):

```
struct TestArray(ulong element_n) {
  int[element_n] elements;

  this(string type)(ulong number) {
pragma(msg, "The type is: " ~ typeof(type).stringof);
  }
}
```

I want to create it and be able to successfully initialize the 
template parameters
of the constructor but until now, I wasn't able to find a way to 
successfully do

that. Is there a way you guys know?  I have tried the following:

```
void main() {
  // Doesn't work
  auto val = TestArray!(10, "int")(60);

  // Doesn't work either
  auto val = TestArray!(10).TestArray!("int")(60);

  // Neither this works
  auto val = TestArray!(10).this!("int")(60);
}
```

As with every question I make, the solution must be "betterC" 
compatible so I can use it.

Thanks a lot!


Re: How can I match every instance of a template type (struct)?

2022-07-12 Thread rempas via Digitalmars-d-learn

On Tuesday, 12 July 2022 at 13:34:42 UTC, rempas wrote:

[...]


Thank you all for your help!

@Ali Çehreli

That makes things much much easier! I'll look at the source code 
in "traits.d" and I'll copy-paste it into my library ;)





Re: How can I match every instance of a template type (struct)?

2022-07-12 Thread rempas via Digitalmars-d-learn

On Tuesday, 12 July 2022 at 13:37:49 UTC, ag0aep6g wrote:


static if (is(typeof(obj) == Test!T, T)) { 
printf("YES!!!\n"); }


Haah? Ok, what does this work anyway? I thought you needed 
parenthesis for more than 1 templated arguments...


How can I match every instance of a template type (struct)?

2022-07-12 Thread rempas via Digitalmars-d-learn

I want to do something like the following:

```d
import core.stdc.stdio;

Test!(T, "mode1") make_test(T)(T data) {
  Test!(T, "mode1") t = { data };

  return t;
}

struct Test(T, string mode = "ref") { T data; }

extern (C) void main() {
  auto obj = make_test(20);
  static if (is(typeof(obj) == Test)) { printf("YES!!!\n"); }
}
```

So, I just want to be able check if a variable is a given struct 
type. I also want to be able to do something similar but having a 
(templated) function that returns a struct type without having to 
be limited to a specific initialization of it.


Obviously, the given code will not work. It will result to the 
following error message:


```
Error: template struct `test.Test(T, string mode = "ref")` is 
used as a type without instantiation; to instantiate it use 
`Test!(arguments)`

```

Any ideas? Also, like in every question I make, the solution must 
be "betterC" compatible.


**CLARIFICATION**
I have a bad feeling that the post is not clear enough, so I'll 
save us all some time by making it clear.

I know I can do this:

```d
  static if (is(typeof(obj) == Test!(int, "mode1"))) { 
printf("YES!!!\n"); }

```

And it will work but this is not what I want. I want to much 
EVERY "Test" type regardless of what's the value

of its templated arguments.


Re: How can I check if a type is a pointer?

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

On Saturday, 25 June 2022 at 14:51:49 UTC, Paul Backus wrote:


Use an [`is()` expression:][1]

```d
if (is(typeof(accepted_type) == T*, T))
{
// it's a pointer
}
```

In English, you read this as "if `typeof(accepted_type)` 
matches the pattern `T*`, where `T` is a type."


If you want to learn more, I recommend reading [Adam Ruppe's 
explanation of `is()` expressions][2].


[1]: https://dlang.org/spec/expression.html#IsExpression
[2]: 
https://forum.dlang.org/post/xklcgjaqggihvhctc...@forum.dlang.org


Thank you too for this example! Have a nice day my friend!


Re: How can I check if a type is a pointer?

2022-06-25 Thread rempas via Digitalmars-d-learn
On Saturday, 25 June 2022 at 14:32:27 UTC, Ola Fosheim Grøstad 
wrote:


I guess you can look at the source code for

https://dlang.org/phobos/std_traits.html#isPointer


Thank you! Nice and quick ;)

For anyone interested, here's the source code:

```d
enum bool isPointer(T) = is(T == U*, U) && __traits(isScalar, T);
```

Have a nice day my friend!


How can I check if a type is a pointer?

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

For example, something like the following:

```d
void main() {
  char accepted_type;
  char* non_accepted_type;

  if (__traits(isPointer, typeof(accepted_type))) {
// The type is not accepted
  }

 else { /* The type is not a pointer so its accepted */ }

  if (__traits(isPointer, typeof(non_accepted_type))) {
// The type is not accepted
  }

 else { /* The type is not a pointer so its accepted */ }
}
```

In that example, the first comparison will execute the second 
branch and for the second comparison,
it will execute the first branch. Of course, this trait doesn't 
exist I used an example to show what I want

to do. Any ideas?


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

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

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

In case someone is wondering, I found an answer in another
forum. The code is the following:

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

void putbytes(char **code, const char *bytes) {
  uint bt;
  for (int i = 0, n; sscanf(bytes + i, "%x%n", , ) == 1; i 
+= n)

{ *(*code)++ = cast(char)bt; }
}

void putdata(char **code, char** data) {
  memcpy(*code, data, (*data).sizeof);
  *code += (*data).sizeof;
}

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

  strcpy(data, "Hello world!\n");

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

  char *pos = code;

  // Call the "write" and "exit" system calls
  putbytes(, "48 C7 C0 1 0 0 0");// mov rax, 0x01 
(write syscall)
  putbytes(, "48 C7 C7 1 0 0 0");// mov rdi, 0x01 
(stdout)
  putbytes(, "48 C7 C2 D 0 0 0");   // mov rdx, 13   
(string length)
  putbytes(, "48 BE");  // movabs rsi, 
data  (string address)

  putdata(, );
  putbytes(, "0F 05");// syscall
  putbytes(, "48 C7 C0 3C 0 0 0");  // mov rax, 0x3C 
(exit syscall)

  putbytes(, "0F 05");   // syscall

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


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: 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 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.


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: Why is the compiled file size so huge?

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

On Friday, 27 May 2022 at 13:40:25 UTC, Alexander Zhirov wrote:
I'm trying to compile a file that weighs 3 kilobytes. I'm also 
linking a self-written dynamic library. I don't understand why 
the resulting executable file is so huge? After all, all 
libraries are present:

[...]


I did a similar question in a C forum regarding an huge file 
sizes of GCC compared to manually writing assembly and linking 
(at least for the smallest possible program on Linux) and well... 
You won't get an answer!


Re: Why isn't my dynamic array method doesn't work for this type?

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

On Friday, 6 May 2022 at 13:35:13 UTC, Steven Schveighoffer wrote:
You don't need to declare an assign operator, the default for 
structs is to member-wise copy all the values.


However, if you do provide one, it will be used.

Note that a simple default can be done like:

```d
ref My_File opAssign(ref My_File s) return {
this.tupleof = s.tupleof;
return this;
}
```

-Steve


Hah! For some reason, I had the idea that it doesn't work 
(meaning it won't compile) without providing an assignment 
operator and that I had test it. I now tested it again and it is 
indeed as you say. Thank you!


Re: Why isn't my dynamic array method doesn't work for this type?

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

On Thursday, 5 May 2022 at 21:07:22 UTC, colleen camacho wrote:
can i use method of Dynamic array in C using malloc library 
function. Program example will create an integer array of any 
length dynamically by asking the array size and array elements 
from user and display on the screen.how memory allocation in C 
programming is done at run time with examples. to integrate an 
api of tracking number like [intelcom courrier canada inc 
tracking](https://couriertrackingfinder.com/intelcom-express-tracking/)?


Thanks for your time! Thankfully, my problem was fixed thanks to 
Steve above! Have a nice day my friend!


Re: Why isn't my dynamic array method doesn't work for this type?

2022-05-05 Thread rempas via Digitalmars-d-learn
On Thursday, 5 May 2022 at 14:20:49 UTC, Steven Schveighoffer 
wrote:

Your assignment operator does nothing.

-Steve


Thanks! That was indeed the problem! In the other data 
structures, it worked without needing explicitly provide one so I 
didn't thought about it. Thanks a lot, you're saving me!


Re: Why isn't my dynamic array method doesn't work for this type?

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

On Thursday, 5 May 2022 at 11:49:29 UTC, vit wrote:


```d
  this.capacity += DEF_VEC_REALLOC_SIZE;
  //realloc(this.ptr, T.sizeof * DEF_VEC_REALLOC_SIZE);
  this.ptr = realloc(this.ptr, T.sizeof * this.capacity); 
//<<--

```


Oh, right! I forgot to say it. I'm using my own `realloc` and not 
the one from libc. So, the `realloc` function is not the problem 
here.


Why isn't my dynamic array method doesn't work for this type?

2022-05-05 Thread rempas via Digitalmars-d-learn
I have created a structure that is a actually an array that 
allocates memory and growths. It is a template and it has worked 
with a couple of types that I have tried with. It doesn't work 
with one tho and I cannot understand why. I will list the 
smallest possible code I could. Keep in mind that it is a couple 
of code. For anyone that wants to read it, keep in mind that I 
have to make this code work with LDC and using "-betterC".


// Filename: "test_file"
```aneluhaein```

// Filename: "my_file.d"
```d
import vec;

struct My_File {
  char tok;
  const char* contents;
  ulong size, ln, cn, pos, identation;

  ref My_File opAssign(ref const My_File s) return { return this; 
}


  // Copy constructor
  this(ref return scope My_File rhs) {
this.tok = rhs.tok;
this.contents = rhs.contents;
this.ln = rhs.ln;
this.cn = rhs.cn;
this.pos = rhs.pos;
this.identation = rhs.identation;
  }

  debug {
void print() {
  printf("
  this.tok = %c
  this.contents = \n\n`\n%s`
  this.ln = %lu
  this.cn = %lu
  this.pos = %lu
  this.identation = %lu",
this.tok,
this.contents,
this.ln,
this.cn,
this.pos,
this.identation,
  );
}
  }
}
```
// Filename: "vec.d"
```d
public import core.stdc.stdlib;
public import core.stdc.stdio;
public import core.sys.posix.fcntl;
public import core.sys.linux.sys.mman;

public enum DEF_VEC_REALLOC_SIZE = 3;
public enum DEF_VEC_ALLOC_SIZE = 3;

void exit_prog(int code) {
  exit(0);
}

struct Vector(T) {
  T* ptr;  // The pointer to the data
  ulong capacity;  // Total amount of objects we can store
  ulong length;// The amount of the objects we have stored

  this(ulong capacity) { // Only used to create the vector that 
will hold the files

this.length = 0;
this.capacity = capacity;
this.ptr = cast(T*)malloc(T.sizeof * capacity);

if (!this.ptr) { // Allocation error check
  fprintf(stderr, "Error: Could not allocate memory for the 
*%s object! Exiting...\n",

  cast(char*)(T).stringof);
  exit_prog(1);
}
  }

  void add(T element) {
if (this.capacity > this.length) {
  this.ptr[this.length++] = element;
}

else {
  this.capacity += DEF_VEC_REALLOC_SIZE;
  realloc(this.ptr, T.sizeof * DEF_VEC_REALLOC_SIZE);

  if (!this.ptr) { // Re-allocation error check
fprintf(stderr, "Error: Could not allocate more memory 
for the *%s object! Exiting...",

cast(char*)(T).stringof);
exit_prog(1);
  }
}
  }

  void inc() {
this.ptr++;
this.length--;
  }
}
```

// Filename: "main.d"
```d
import core.stdc.stdlib;
import core.stdc.stdio;

import my_file;
import vec;

extern (C) void main() {
  auto modules = Vector!(My_File)(DEF_VEC_ALLOC_SIZE);
  const char* filename = "/tmp/test_file";
  int fd = open(filename, O_RDWR);

  ulong file_size = 24;
  const char* contents = cast(char*)mmap(null,
file_size, PROT_READ, MAP_PRIVATE, fd, 0
  );

  My_File file = {
'T',
contents,
file_size,
1, 2, 3, 4
  };

  debug printf("\n\nBEFORE ADDING IT TO THE MODULE\n");
  file.print();

  modules.add(file);

  debug printf("\n\n\nAFTER ADDING IT TO THE MODULE\n");
  modules.ptr.print();
  puts("");
  exit(0);
}
```


Re: Create an associative array with function pointers as the value

2022-04-20 Thread rempas via Digitalmars-d-learn
On Wednesday, 20 April 2022 at 14:29:33 UTC, rikki cattermole 
wrote:


On 21/04/2022 2:15 AM, rempas wrote:
Unfortunately, this will not work for me as it uses "TypeInfo" 
and it is not available with "-betterC". Thank you for trying 
to help regardless!


You can't use AA's in -betterC.

The implementation is not templated and is in druntime.


Oh! Thank you! I'm an idiot for not knowing that...


Re: Create an associative array with function pointers as the value

2022-04-20 Thread rempas via Digitalmars-d-learn

On Wednesday, 20 April 2022 at 11:10:18 UTC, vit wrote:

You need shared static this for initializing immutable AA:

```d
immutable void function(ref file_struct)[string] 
common_identifiers;


shared static this(){
common_identifiers = [
  "let" : _let,
  // "macro"   : _macro,
];
}
```


Unfortunately, this will not work for me as it uses "TypeInfo" 
and it is not available with "-betterC". Thank you for trying to 
help regardless!


Create an associative array with function pointers as the value

2022-04-20 Thread rempas via Digitalmars-d-learn
I'm trying to create an associative array where the keys will be 
a "string" type and the values will be function pointers. I'm 
using a custom type is called "file_struct" and for anyone that 
wants to try specifically with this type, the definition is the 
following:


```d
struct file_struct {
  FILE* file;
  const char* name;
  size_t ln, cn, size;
  str identifier, type_buffer, type_buffer_tmp;

  void inc_ln() {
this.cn = 0;
this.ln++;
  }
}
```

The function pointers will point to a function that doesn't 
return anything and takes only one parameter that is of my custom 
"file_struct" type. More specifically, the signature is the 
following:


```d
void function(ref file_struct)
```

So with that been said, I tried to create an associative array 
with the following code:


```d
// Suppose that the function exists in another file
void parse_let(ref file_struct file) {}

immutable void function(ref file_struct)[string] 
common_identifiers = [

  "let" : _let,
  // "macro"   : _macro,
];
```

When I try to compile it (I can only compile with "ldc2" because 
my code contains gcc-style inline assembly), I get the following 
error message:


```
main.d(12,71): Error: expression `["let":& parse_let]` is not a 
constant

```

Of course the file name and the number of line is relative to me 
case. Any ideas?


Re: Is it safe to read to memory after it has been allocated with `pureMalloc` and `pureRealloc`?

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

On Monday, 4 April 2022 at 09:26:13 UTC, Stanislav Blinov wrote:
No. Neither `malloc` nor `realloc` (for which D's `pure...` 
variants are mere wrappers) are specified to initialize 
allocated memory. `calloc`, however, is - it initializes 
allocated block with zeroes.


Thanks, that's what I was looking for! I'll switch to `calloc` 
instead. Have a great day!


Re: Is it safe to read to memory after it has been allocated with `pureMalloc` and `pureRealloc`?

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

On Monday, 4 April 2022 at 07:39:08 UTC, Salih Dincer wrote:

On Monday, 4 April 2022 at 07:32:00 UTC, rempas wrote:


Does anyone knows what's going on here?


Source code?


Why does it matter?

```
import core.memory;
import core.stdc.stdio;
import core.stdc.stdlib;

extern (C) void main() {
  char* str = cast(char*)pureMalloc(23);
  str[0] = 'J';
  str[1] = 'o';
  str[2] = 'h';
  str[3] = 'n';

  printf("My name is: %s\n", str);
  exit(0);
}
```

Maybe, I didn't explained it properly. The example works. 
However, I wonder if it randomly works or if it is safe to do 
something like that as if the bytes have been initialized to '\0'.


Is it safe to read to memory after it has been allocated with `pureMalloc` and `pureRealloc`?

2022-04-04 Thread rempas via Digitalmars-d-learn
In other terms, do these functions auto-initialize memory to be 
ready for use? I test it out using `printf` to print a string. 
"%s" expects for a null terminated string and it seems to work so 
I suppose that these functions auto-initialize the bytes to `\0`.


However, memory is tricky and I still don't know how memory (and 
virtual memory) works under the hood so it may just randomly work 
and it may give me a segmentation fault at some point.


Does anyone knows what's going on here?


Re: Will it be possible to write a GCC frontend in D?

2022-02-23 Thread rempas via Digitalmars-d-learn
On Wednesday, 23 February 2022 at 21:33:00 UTC, Adam D Ruppe 
wrote:


There is no branch, it is just part of the upstream mainline. 
see:


https://gcc.gnu.org/git/?p=gcc.git;a=tree;f=gcc/d/dmd;h=454baa71a0d270fb891acdda6fd0215a3d6cb588;hb=HEAD


Oh, this is what I mean by saying "branch" so my mistake. Thanks 
for the info!


and yeah it is extern(C++). importC isn't going to be helpful, 
but still, gdc proves you can make a gcc frontend in d.


Yeah, If you put it that way. Tbh, I already knew it was possible 
to do is this way because I know GDC's frontend was written in D. 
However, I was wondering if we can have C bindings but it seems 
that's not the case.


Re: Will it be possible to write a GCC frontend in D?

2022-02-23 Thread rempas via Digitalmars-d-learn
On Wednesday, 23 February 2022 at 20:19:04 UTC, Adam D Ruppe 
wrote:


I should hope so, otherwise gdc wouldn't exist, yet it does.


[extern 
(C++)](https://github.com/D-Programming-GDC/gdc/tree/master/gcc/d/dmd) and manually creating the decorations. At least that's my understanding of browsing the source and that was until 2018. Do you know where is the updated GDC branch btw?


Re: Will it be possible to write a GCC frontend in D?

2022-02-23 Thread rempas via Digitalmars-d-learn

On Wednesday, 23 February 2022 at 20:06:58 UTC, bachmeier wrote:


Not sure if this is the same thing (a link would have helped) 
but [this is done in 
C](https://www.cs.usfca.edu/~galles/compilerdesign/C/csupport.html)


Thank you! However, one things that I didn't mentioned is that 
GCC was once written in C but now it is written in C++ so the 
date this was created matters.


Will it be possible to write a GCC frontend in D?

2022-02-23 Thread rempas via Digitalmars-d-learn
I'm using a book called "modern compiler design (version 2)" to 
learn how to create compiler and I thought about learning and 
applying this knowledge on writing a GCC frontend just for fun to 
see where this gets me. However, I've seen some tutorials and 
I've seen people doing it in C++. Now, I want to do it in D (of 
course!). My problem is that I don't if the headers are using C++ 
features because If this is possible then I won't be able to use 
ImportC to "automatically" get bindings to use in D. Any ideas?


  1   2   3   >