Re: GC seems to crash my C-code function
On Thursday, 16 September 2021 at 18:02:44 UTC, Steven Schveighoffer wrote: Are you sure? Be very pedantic about what C functions do with the data you send it. Sometimes they store it somewhere to use later. Sometimes they expect it to be allocated by the C heap, etc. Without seeing how you use it, I can't tell you if it's wrong or not. If you want to have a look the original C-library is here https://github.com/rdoeffinger/iec16022 I'm only using the encoder function iec16022ecc200f. If it's a literal, you don't need to toStringz (which also allocates). All string literals are zero-terminated (and actually implicitly castable to `immutable char *`). -Steve Thanks, I'm just careful with casting. Does it really allocate from a literal if it's used on the stack only? Is `-vgc` switch reliable?
Re: Merge 2 structs together (into a single struct)?
On Friday, 17 September 2021 at 05:01:36 UTC, james.p.leblanc wrote: Again, thanks to you and many of the D community with helping to learn and appreciate the capabilities of D. It is nice to be here. Yeah. The improved joinStruct is nice enough that I think it's probably a good thing to do. And there's this, some kind of Jai innovation: ```d struct Object { float[2] position, velocity, facing; float size; } struct Player { mixin parent!Object; int hp; } mixin template parent(Struct) { static foreach (i, alias f; Struct.tupleof) { mixin("typeof(f) ", __traits(identifier, f), " = Struct.init.tupleof[i];"); } } void main() { import std.stdio : writeln; writeln(Player([0, 0], [0, 0], [0, -1], 5.0, 100)); } ```
Re: Merge 2 structs together (into a single struct)?
On Friday, 17 September 2021 at 00:36:42 UTC, ag0aep6g wrote: On 16.09.21 22:53, jfondren wrote: string joinstruct(A, B)(string name) { struct JoinStruct(Structs ...) { static foreach (S; Structs) { static foreach (i, alias f; S.tupleof) { mixin("typeof(f) ", __traits(identifier, f), " = S.init.tupleof[i];"); Ali, jfondren, ag0aep6g, All of your responses are greatly appreciated. I have done test implementations of them all, and they work well with my intended application. (Also, I learned something new from all of them). The struct mixin template appears to be quite robust and elegant. So, I include a simple implementation for any future readers to take it for a "test drive". ```d import std.stdio; import std.traits; template JoinStruct(Structs ...) { static foreach (S; Structs) { static foreach(i, alias f; S.tupleof) { mixin("typeof(f) ", __traits(identifier, f), " = S.init.tupleof[i];"); } } } void main(){ struct A { int alpha; float x = 1.23; } struct B { int beta; float y = 4.4; string s = "this is fine."; } struct C { int gamma = 42; double z = 1.2e8; string t = "if this was named 's', duplicate would be detected at compile time"; } struct D { mixin JoinStruct!(A,B,C); } A a; B b; C c; writeln("\na:", a); writeln("\nb:", b); writeln("\nc:", c) auto d = D(); writeln("\nd:", d); } ``` My next steps would be to include some UDA's to ease the getopt building for command line arguments. There is a sketch from Jesse Phillips at https://dev.to/jessekphillips/argument-parsing-into-structure-4p4n For example: ```d // Specify The Parameter Structure struct Options { @Option("threads", "t") @Help("Number of threads to use.") size_t threads; @Option("file") @Help("Input files") string[] files; } ``` Again, thanks to you and many of the D community with helping to learn and appreciate the capabilities of D. It is nice to be here. Best Regards, James
Re: Merge 2 structs together (into a single struct)?
On 16.09.21 22:53, jfondren wrote: string joinstruct(A, B)(string name) { string s = "struct " ~ name ~ " {"; alias memA = __traits(allMembers, A); alias memB = __traits(allMembers, B); alias initA = A.init.tupleof; alias initB = B.init.tupleof; static foreach (i; 0 .. memA.length) { s ~= typeof(__traits(getMember, A, memA[i])).stringof; s ~= " "; s ~= memA[i]; s ~= " = "; s ~= initA[i].stringof; s ~= ";\n"; } static foreach (i; 0 .. memB.length) { s ~= typeof(__traits(getMember, B, memB[i])).stringof; s ~= " "; s ~= memB[i]; s ~= " = "; s ~= initB[i].stringof; s ~= ";\n"; } s ~= "}"; return s; } As a rule of thumb, don't use `stringof` for string mixins. There's usually a better way. In this case, if you make `joinstruct` a struct template, you can use the types and init values of the fields directly, without converting them to strings and back. Only the names need to be mixed in as strings. struct JoinStruct(Structs ...) { static foreach (S; Structs) { static foreach (i, alias f; S.tupleof) { mixin("typeof(f) ", __traits(identifier, f), " = S.init.tupleof[i];"); } } }
Re: dub segfault and range error handling
On Thursday, 16 September 2021 at 20:49:28 UTC, seany wrote: I compile with : `dub build -b release --compiler=ldc2` The result executing the compiled binary 'myproj' is is ( whether `writeln (a[1])` is uncommented, or the `test()` function is uncommented) some random number, usually negative with large absolute value, such as `-1894658200` . If this is embedded in a class, then the result is segfault. Is this expected behavior? Yes. You have a -release build, "defaulting to disabled asserts/contracts/invariants, and bounds checks in @safe functions only", and you have an array out of bounds in a @system function, so your array out of bounds goes unchecked.
Re: What is the meaning of @future ?
On Thursday, 16 September 2021 at 20:53:34 UTC, Elmar wrote: Hello D community. I was browsing the `__traits` keywords and I found `isFuture` whose descriptions says something about `@future`-annotated variables. [link](https://dlang.org/spec/traits.html#isFuture) I didn't find anything about `@future` for the D programming language. I only found that this annotation is used in Apex to denote futures (a.k.a. promises) as programming concept. Is this something which exists, existed, was abandoned early as an idea? I remember I had read that D uses a "fiber" library to provide coroutines and such. Maybe somebody knows an answer for this. future means a name is reserved for future extension. it's kind of the opposite of deprecated.
What is the meaning of @future ?
Hello D community. I was browsing the `__traits` keywords and I found `isFuture` whose descriptions says something about `@future`-annotated variables. [link](https://dlang.org/spec/traits.html#isFuture) I didn't find anything about `@future` for the D programming language. I only found that this annotation is used in Apex to denote futures (a.k.a. promises) as programming concept. Is this something which exists, existed, was abandoned early as an idea? I remember I had read that D uses a "fiber" library to provide coroutines and such. Maybe somebody knows an answer for this.
Re: Merge 2 structs together (into a single struct)?
On Thursday, 16 September 2021 at 20:12:03 UTC, james.p.leblanc wrote: Is there some obvious, and simple solution to this conundrum of mine? I would consider AAs. ```d struct A { int alpha; float x = 1.23; } struct B { int beta; float y = 4.4; string s = "this is fine."; } string joinstruct(A, B)(string name) { string s = "struct " ~ name ~ " {"; alias memA = __traits(allMembers, A); alias memB = __traits(allMembers, B); alias initA = A.init.tupleof; alias initB = B.init.tupleof; static foreach (i; 0 .. memA.length) { s ~= typeof(__traits(getMember, A, memA[i])).stringof; s ~= " "; s ~= memA[i]; s ~= " = "; s ~= initA[i].stringof; s ~= ";\n"; } static foreach (i; 0 .. memB.length) { s ~= typeof(__traits(getMember, B, memB[i])).stringof; s ~= " "; s ~= memB[i]; s ~= " = "; s ~= initB[i].stringof; s ~= ";\n"; } s ~= "}"; return s; } unittest { mixin(joinstruct!(A, B)("C")); import std.stdio; writeln(C()); } ```
Re: dub segfault and range error handling
On Thursday, 16 September 2021 at 20:49:28 UTC, seany wrote: I create a new project with : `dub init myproj`. Then I change the source/app.d file with this : [...] PS :compiling with : `dub build -b release ` ( i.e. no ldc2) is a direct segfault of the code posted above. PPS : my system is : Linux glassplanet 5.9.16-1-MANJARO #1 SMP PREEMPT Mon Dec 21 22:00:46 UTC 2020 x86_64 GNU/Linux
Re: Merge 2 structs together (into a single struct)?
On 9/16/21 1:12 PM, james.p.leblanc wrote: > I really thought that this would be a simple enough > small project in meta programming/reflection. It should be doable. One question is how to resolve conflicting members of the two structs, which can be defaulted to one of the policies "cause compilation error", "do name mangle", "ignore second", etc. > the point of this is really to use the struct AB > for getopt reading of command line options. I pass local variables to getopt and then construct a struct from them: int a; double d; getopt(/* ... */, &a, /* ... */, &d); myFunction(MyStruct(a, d)); Do you want to pass members of a struct to getopt? auto m = MyStruct(); getopt(/* ... */, &m.a, /* ... */, &m.d); Ali
dub segfault and range error handling
I create a new project with : `dub init myproj`. Then I change the source/app.d file with this : ` import std.stdio; import std.math; import std.stdio; import std.conv; import std.format; import std.math; import std.algorithm; import std.net.curl; import std.json; //import dlib.image; import std.path; import std.array; import std.net.curl; import core.stdc.stdlib; import std.datetime; import std.file; //import opmix.dup; import std.parallelism; import std.exception; import core.exception; void main() { int[] a = new int[] (0); try { // writeln(a[1]); test(); } catch ( RangeError re) { writeln("wrong"); } catch (Throwable T){ writeln("something else"); } } void test() { int [] b = new int[0]; int c = b[4]; writeln(c); } ` I compile with : `dub build -b release --compiler=ldc2` The result executing the compiled binary 'myproj' is is ( whether `writeln (a[1])` is uncommented, or the `test()` function is uncommented) some random number, usually negative with large absolute value, such as `-1894658200` . If this is embedded in a class, then the result is segfault. Is this expected behavior? Thank you.
Re: Array permutations
I also should discourage its current form with large `tupleSize`s. The computation is in O(exp(values.length)). Instead of `~=` I would suggest an `std.array.appender` of arrays instead of an 2D-array for the `choices`, if the `choices` become large. Most efficient is a preallocated array capacity. In that case `~=` has very low overhead.
Merge 2 structs together (into a single struct)?
Dear All, I really thought that this would be a simple enough small project in meta programming/reflection. Consisely, merge two structures, which are coming from two different elements of the code base. (One contains standard input options for getopt, and the other is for user customization for getopt.) And while there are many hints, and partial solutions among forum posts, and books, my many attempts have not been successful. Is there some obvious, and simple solution to this conundrum of mine? ```d struct A { int alpha; float x = 1.23; } struct B { int beta; float y = 4.4; string s = "this is fine."; } ``` some static foreach magic, and mixins later ... we have the merger ```d struct AB { int alpha; float x = 1.23; int beta; float y = 4.4; string s = "this is fine."; } ``` ... the point of this is really to use the struct AB for getopt reading of command line options. All pointers, tips and info are greatly appreciated. Best Regards, James
Re: Array permutations
On Saturday, 11 September 2021 at 19:37:42 UTC, Vino wrote: Hi All, Request your help on the below to print the below array as "Required output", Was able to get these values "[1,2],[2,3],[3,4],[4,5]" by using list.slide(2), need your help to get values "1,3],[1,4],[1,5],[2,4],[2,5],[3,5]" auto list[] = [1,2,3,4,5] Required output [1,2],[2,3],[3,4],[4,5],[1,3],[1,4],[1,5],[2,4],[2,5],[3,5] From, Vino Would this be a valid solution to your problem? ```D pure @safe nothrow T[][] computeChoices(T)(T[] values, size_t tupleSize = 2) { if (tupleSize == 0) { return [[]]; } T[][] choices = []; tupleSize--; foreach(i, element; values[0 .. $ - tupleSize]) { import std.algorithm.iteration : map; import std.array : array; choices ~= computeChoices(values[i+1 .. $], tupleSize) .map!(choice => element ~ choice) .array; } return choices; } unittest { assert(computeChoices([1, 2, 3, 4, 5], 2) == [[1,2], [1,3], [1,4], [1,5], [2,3], [2,4], [2,5], [3,4], [3,5], [4,5]] ); } ``` You can choose in the 2nd parameter how large the inner arrays should be. It uses GC to allocate the result via the function `array`. If that is a problem, you could choose an allocator from `std.experimental.allocator` and use the `makeArray` function with the allocator instead of the `array` function. (Manual deallocation could be required then as well.)
Re: GC seems to crash my C-code function
On 9/16/21 1:08 PM, frame wrote: On Thursday, 16 September 2021 at 15:34:25 UTC, Steven Schveighoffer wrote: `dup` is a GC allocation. Are you using that in your C code? the GC might be collecting that string. The compiler doesn't show that lines with -vgc. Maybe it knows that it is only stack allocated? Technically, the GC could collect that data if it wants - it's not longer used after the function returns. At least I control that the GC cannot collect it till my data is processed, so there should be no problem. Are you sure? Be very pedantic about what C functions do with the data you send it. Sometimes they store it somewhere to use later. Sometimes they expect it to be allocated by the C heap, etc. Without seeing how you use it, I can't tell you if it's wrong or not. I guess the C-methods did corrupt the memory which the compiler has reserved for that function data statically and then the GC collect marks it as free or some other UB. You are better off to cast away the immutable (as long as you are 100% sure the C code isn't writing to it), as the string literal will not be collected. Yes, I changed it to stringz and a cast and the problem is gone so far. All char* are read only in the function or passed to stdlib functions that should not modify it. If it's a literal, you don't need to toStringz (which also allocates). All string literals are zero-terminated (and actually implicitly castable to `immutable char *`). -Steve
Re: GC seems to crash my C-code function
On Thursday, 16 September 2021 at 15:34:25 UTC, Steven Schveighoffer wrote: `dup` is a GC allocation. Are you using that in your C code? the GC might be collecting that string. The compiler doesn't show that lines with -vgc. Maybe it knows that it is only stack allocated? Technically, the GC could collect that data if it wants - it's not longer used after the function returns. At least I control that the GC cannot collect it till my data is processed, so there should be no problem. I guess the C-methods did corrupt the memory which the compiler has reserved for that function data statically and then the GC collect marks it as free or some other UB. You are better off to cast away the immutable (as long as you are 100% sure the C code isn't writing to it), as the string literal will not be collected. -Steve Yes, I changed it to stringz and a cast and the problem is gone so far. All char* are read only in the function or passed to stdlib functions that should not modify it.
Re: GC seems to crash my C-code function
On 9/16/21 6:28 AM, frame wrote: I have C-code translated in D that acts sometimes incorrect if the GC has made some collect. I would like to know why. - Code runs correct if the GC collections are off - There are no allocations within the C-translated-code except `throw new` (but they are not called) ... I didn't want to change the code much so I have some piece like that: ```d // const char *s2 = "!\"#$%&'()*+,-./:;<=>?@[\\]^_"; char* s2 = "!\"#$%&'()*+,-./:;<=>?@[\\]^_".dup.ptr; ``` Could this cause the issue? But the pointer is not used outside the function where it's created. `dup` is a GC allocation. Are you using that in your C code? the GC might be collecting that string. You are better off to cast away the immutable (as long as you are 100% sure the C code isn't writing to it), as the string literal will not be collected. -Steve
Re: GC seems to crash my C-code function
On Thursday, 16 September 2021 at 11:35:27 UTC, frame wrote: On Thursday, 16 September 2021 at 11:11:56 UTC, bauss wrote: On Thursday, 16 September 2021 at 11:06:04 UTC, frame wrote: On Thursday, 16 September 2021 at 10:48:19 UTC, bauss wrote: Use toStringz and not .ptr. Or append \0 to your string. Stupid me should really know that already, thanks =) Of course I have dup'ed the \0 from the string away... But still I don't know why it works if the GC is off? Did you see my second response? Yes, but as I mentioned this pointer data isn't hold outside the function and the GC collect runs after data is processed, not in between. This pointer should be fully stack allocated and also newly generated each time the function is called, so I see no impact by the GC? But GC collecting works now without issues. My guess is something is undefined behavior in the C code, idk really
Re: GC seems to crash my C-code function
On Thursday, 16 September 2021 at 11:11:56 UTC, bauss wrote: On Thursday, 16 September 2021 at 11:06:04 UTC, frame wrote: On Thursday, 16 September 2021 at 10:48:19 UTC, bauss wrote: Use toStringz and not .ptr. Or append \0 to your string. Stupid me should really know that already, thanks =) Of course I have dup'ed the \0 from the string away... But still I don't know why it works if the GC is off? Did you see my second response? Yes, but as I mentioned this pointer data isn't hold outside the function and the GC collect runs after data is processed, not in between. This pointer should be fully stack allocated and also newly generated each time the function is called, so I see no impact by the GC? But GC collecting works now without issues.
Re: GC seems to crash my C-code function
On Thursday, 16 September 2021 at 11:06:04 UTC, frame wrote: On Thursday, 16 September 2021 at 10:48:19 UTC, bauss wrote: Use toStringz and not .ptr. Or append \0 to your string. Stupid me should really know that already, thanks =) Of course I have dup'ed the \0 from the string away... But still I don't know why it works if the GC is off? Did you see my second response?
Re: GC seems to crash my C-code function
On Thursday, 16 September 2021 at 10:48:19 UTC, bauss wrote: Use toStringz and not .ptr. Or append \0 to your string. Stupid me should really know that already, thanks =) Of course I have dup'ed the \0 from the string away... But still I don't know why it works if the GC is off?
Re: GC seems to crash my C-code function
On Thursday, 16 September 2021 at 10:48:19 UTC, bauss wrote: On Thursday, 16 September 2021 at 10:28:37 UTC, frame wrote: I have C-code translated in D that acts sometimes incorrect if the GC has made some collect. I would like to know why. - Code runs correct if the GC collections are off - There are no allocations within the C-translated-code except `throw new` (but they are not called) - All allocations made in C-translated-code are still calloc/malloc `ed - Even if I disable the GC before calling the function and just enable it after there will be an incorrect result - Data passed to the function belongs to a struct and the function is called in a member function and is always correct The main public function accepts a char* and returns a char*. Signature is like this: ```d char* fun(ref int, ref int, size_t, const char*, out int, out int, out int, uint); ``` Input paramter gets the pointer from char[] `.ptr` property (and length must be supplied too). I didn't want to change the code much so I have some piece like that: ```d // const char *s2 = "!\"#$%&'()*+,-./:;<=>?@[\\]^_"; char* s2 = "!\"#$%&'()*+,-./:;<=>?@[\\]^_".dup.ptr; ``` Could this cause the issue? But the pointer is not used outside the function where it's created. Use toStringz and not .ptr. Or append \0 to your string. Also see the documentation for "toStringz" which has this: ``` Important Note: When passing a char* to a C function, and the C function keeps it around for any reason, make sure that you keep a reference to it in your D code. Otherwise, it may become invalid during a garbage collection cycle and cause a nasty bug when the C code tries to use it. ``` It probably should tell that somewhere else too.
Re: GC seems to crash my C-code function
On Thursday, 16 September 2021 at 10:28:37 UTC, frame wrote: I have C-code translated in D that acts sometimes incorrect if the GC has made some collect. I would like to know why. - Code runs correct if the GC collections are off - There are no allocations within the C-translated-code except `throw new` (but they are not called) - All allocations made in C-translated-code are still calloc/malloc `ed - Even if I disable the GC before calling the function and just enable it after there will be an incorrect result - Data passed to the function belongs to a struct and the function is called in a member function and is always correct The main public function accepts a char* and returns a char*. Signature is like this: ```d char* fun(ref int, ref int, size_t, const char*, out int, out int, out int, uint); ``` Input paramter gets the pointer from char[] `.ptr` property (and length must be supplied too). I didn't want to change the code much so I have some piece like that: ```d // const char *s2 = "!\"#$%&'()*+,-./:;<=>?@[\\]^_"; char* s2 = "!\"#$%&'()*+,-./:;<=>?@[\\]^_".dup.ptr; ``` Could this cause the issue? But the pointer is not used outside the function where it's created. Use toStringz and not .ptr. Or append \0 to your string.
GC seems to crash my C-code function
I have C-code translated in D that acts sometimes incorrect if the GC has made some collect. I would like to know why. - Code runs correct if the GC collections are off - There are no allocations within the C-translated-code except `throw new` (but they are not called) - All allocations made in C-translated-code are still calloc/malloc `ed - Even if I disable the GC before calling the function and just enable it after there will be an incorrect result - Data passed to the function belongs to a struct and the function is called in a member function and is always correct The main public function accepts a char* and returns a char*. Signature is like this: ```d char* fun(ref int, ref int, size_t, const char*, out int, out int, out int, uint); ``` Input paramter gets the pointer from char[] `.ptr` property (and length must be supplied too). I didn't want to change the code much so I have some piece like that: ```d // const char *s2 = "!\"#$%&'()*+,-./:;<=>?@[\\]^_"; char* s2 = "!\"#$%&'()*+,-./:;<=>?@[\\]^_".dup.ptr; ``` Could this cause the issue? But the pointer is not used outside the function where it's created.