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-07 Thread FeepingCreature via Digitalmars-d-learn

On Wednesday, 1 March 2023 at 09:37:48 UTC, rempas wrote:
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?


Yay!

(Definitely make a compiler, it's a great way to learn.)

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

```
$ grep SIGSEGV /usr/include/bits -R
/usr/include/bits/signum-generic.h:#define  SIGSEGV 
11  /* Invalid access to storage.  */

```

As per the POSIX spec 
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_21_18. signal exits must be reported with exit codes above 128. Customarily, shells will simply add 128 to the signal:


```
$ cat test.c; gcc test.c -otestc; ./testc; echo $?
int main() { int* ip = 0; *ip = *ip; return 0; }
Segmentation fault
139
```

139 being 128 + 11, but POSIX does not specify *how* the signal 
code is converted to an exit code. For instance, Python reports a 
signal 11 exit as -11. Strictly speaking, -11 is "above 128" in 
two's complement, corresponding to unsigned 245. But I don't know 
why Python does this. Presumably your shell does it the same way?


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

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

On Wednesday, 1 March 2023 at 09:37:48 UTC, rempas wrote:
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?


Yay!

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

```
$ grep SIGSEGV /usr/include/bits -R
/usr/include/bits/signum-generic.h:#define  SIGSEGV 
11  /* Invalid access to storage.  */

```

As per the POSIX spec 
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_21_18. signal exits must be reported with exit codes above 128. Customarily, shells will simply add 128 to the signal:


```
$ cat test.c; gcc test.c -otestc; ./testc; echo $?
int main() { int* ip = 0; *ip = *ip; return 0; }
Segmentation fault
139
```

139 being 128 + 11, but POSIX does not specify *how* the signal 
code is converted to an exit code. For instance, Python reports a 
signal 11 exit as -11. Strictly speaking, -11 is "above 128" in 
two's complement, corresponding to unsigned 245. But I don't know 
why Python does this. Presumably your shell does it the same way?


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?


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

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

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

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


To expand on this:

```d
uint32_t[2] value;
uint32_t* value_ptr = value.ptr;
// We are allowed to access the pointer at index 0
// because we declared the value it points to, to be size 2.
value_ptr[0] = 0;
// This is also allowed, because `value_ptr` is
// a pointer to two sequential `uint32_t` in memory.
value_ptr[1] = 0;
// But this access would segfault, because it's trying to write
// to the third element of a two-element array:
value_ptr[2] = 0;
```

Note: I just lied; `value_ptr[2]` would not segfault, for 
somewhat technical reasons; but it *would* corrupt your program's 
memory. At any rate, it's an invalid operation.




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

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

On Wednesday, 1 March 2023 at 08:12:05 UTC, rempas wrote:
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?


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);
```



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?