Re: How to implement this?
On Friday, 8 April 2022 at 05:46:56 UTC, Elvis Zhou wrote: On Friday, 8 April 2022 at 04:31:45 UTC, Elvis Zhou wrote: [...] I know where the issue comes from, dynamic array is GCed and save the reference of a local variable in GCed memory is not allowed, but here structs is assumed to not escape, it can be simply achieved by using a fixed-size array instead, ie A*[32] structs; int i = 0; structs[i++] = cast(A*) However I wonder if there be a stack allocated array with max capacity limits, which can be concated like with normal dynamic one. like, assumeNoEscapeOrWhatever!DynamicArray structs; structs ~= cast(A*) is it possible?
Re: How to implement this?
On Friday, 8 April 2022 at 04:31:45 UTC, Elvis Zhou wrote: struct A {} struct B { A a; } struct C { A a; } A*[] structs; B b; init(); structs ~= cast(A*) //Error: copying `cast(A*)& b` into allocated memory escapes a reference to local variable `b` C c; init(); structs ~= cast(A*) //Error: copying `cast(A*)& c` into allocated memory escapes a reference to local variable `c` batch_process(structs); I know where the issue comes from, dynamic array is GCed and save the reference of a local variable in GCed memory is not allowed, but here structs is assumed to not escape, it can be simply achieved by using a fixed-size array instead, ie A*[32] structs; int i = 0; structs[i++] = cast(A*) However I wonder if there be a stack allocated array with max capacity limits, which can be concated like with normal dynamic one.
Re: How to implement this?
On 4/7/22 21:31, Elvis Zhou wrote: > > struct A {} > struct B { A a; } > struct C { A a; } > > A*[] structs; > > B b; > init(); > structs ~= cast(A*) > //Error: copying `cast(A*)& b` into allocated memory escapes a reference > to local variable `b` If that really is the case, you want to place the objects on memory that will not go away. Dynamic arrays provide "memory" that is owned by the GC. The following program emplaces alternating Bs and Cs into a buffer and then batch_process'es them: struct A { int i; } struct B { A a; } struct C { A a; } A*[] structs; void append(T, Args...)(ref ubyte[] structs, Args args) { import std.conv : emplace; structs.length += sizeWithPadding!T; auto where = cast(T*)([$ - sizeWithPadding!T]); emplace(where, args); } void main() { ubyte[] structs; foreach (i; 0 .. 10) { if (i % 2) { structs.append!B(A(i)); } else { structs.append!C(A(i)); } } batch_process(structs); } auto process(T)(const(ubyte)[] structs) { import std.stdio : writeln; writeln(*cast(T*)structs.ptr); return structs[sizeWithPadding!T..$]; } void batch_process(const(ubyte)[] structs) { import std.range : empty; for (size_t i = 0; !structs.empty; i++) { if (i % 2) { structs = structs.process!B(); } else { structs = structs.process!C(); } } } T * nextAlignedAddress(T)(T * candidateAddr) { import std.traits; static if (is (T == class)) { const alignment = classInstanceAlignment!T; } else { const alignment = T.alignof; } const result = (cast(size_t)candidateAddr + alignment - 1) / alignment * alignment; return cast(T*)result; } void * nextAlignedAddress(T)(void * candidateAddr) { return nextAlignedAddress(cast(T*)candidateAddr); } size_t sizeWithPadding(T)() { static if (is (T == class)) { const candidateAddr = __traits(classInstanceSize, T); } else { const candidateAddr = T.sizeof; } return cast(size_t)nextAlignedAddress(cast(T*)candidateAddr); } I copied nextAlignedAddress() and sizeWithPadding() functions from this chapter: http://ddili.org/ders/d.en/memory.html Everything I did in the program above is explained there. Ali
Re: How to implement this?
On Friday, 8 April 2022 at 04:54:35 UTC, Era Scarecrow wrote: Maybe it should be `cast(A*) `? Confusing HTML entities bit on here. Probably just ignore it. Maybe you are doing it backwards. What if you had ```d struct B { A* a; } A[] arraylist; ``` then in the init append a new item to A's array list, before doing: ```d arraylist ~= A(); a = [$-1]; ``` Alternately, add a static list and have the batch function access both lists? ```d struct B { static A[] list; int a_index=-1; } a_index=list.length; list ~= A(); ``` then reference the item by list[a_index] or something similar.
Re: How to implement this?
On Friday, 8 April 2022 at 04:31:45 UTC, Elvis Zhou wrote: B b; init(\); structs ~= cast(A*)\ //Error: copying `cast(A*)\& b` into allocated memory escapes a reference to local variable `b` Maybe it should be `cast(A*) \`?
How to implement this?
struct A {} struct B { A a; } struct C { A a; } A*[] structs; B b; init(); structs ~= cast(A*) //Error: copying `cast(A*)& b` into allocated memory escapes a reference to local variable `b` C c; init(); structs ~= cast(A*) //Error: copying `cast(A*)& c` into allocated memory escapes a reference to local variable `c` batch_process(structs);
Re: Again, ask help with Dlang program footprint
On Friday, 8 April 2022 at 03:20:29 UTC, dangbinghoo wrote: hi, I just asked for help about this before, on that time, my solution is to remove whatever dub dependencies which are optional. now, I'm re-examining the dlang program footprint size, and I put a github example repo here: https://github.com/dangbinghoo/dlang_footprint_test.git the example is simply a json ser/deser test depends on ASDF, on my machine it generates a binary about 914K using LDC2. Note: as I'm focused on embedded system development, what I want help with is only for the situation using LDC compiler. thanks! PS: I need the program link Phobos statically, don't want to use .so except the basic C library. so I added option `-link-defaultlib-shared=false` in dub.json by default, this should not be changed.
Again, ask help with Dlang program footprint
hi, I just asked for help about this before, on that time, my solution is to remove whatever dub dependencies which are optional. now, I'm re-examining the dlang program footprint size, and I put a github example repo here: https://github.com/dangbinghoo/dlang_footprint_test.git the example is simply a json ser/deser test depends on ASDF, on my machine it generates a binary about 914K using LDC2. Note: as I'm focused on embedded system development, what I want help with is only for the situation using LDC compiler. thanks!
Re: Looking for a workaround
On Thursday, 7 April 2022 at 12:56:05 UTC, MoonlightSentinel wrote: On Wednesday, 6 April 2022 at 18:10:32 UTC, Guillaume Piolat wrote: Any idea how to workaround that? I really need the same UDA in parent and child class. Use a frontend >= dmd 2.099, it works according to run.dlang.io. Good to know, thanks.
Re: A weird example of .toUTF16z concatination side-effects in wcsncat
On Thursday, 7 April 2022 at 12:51:26 UTC, Stanislav Blinov wrote: On Thursday, 7 April 2022 at 10:50:35 UTC, BoQsc wrote: wchar_t* clang_string = cast(wchar_t *)"AA"; You're witnessing undefined behavior. "AA" is a string literal and is stored in the data segment. Mere cast to wchar_t* does not make writing through that pointer legal. Moreover, even if it was legal to write through it, that alone wouldn't be sufficient. From documentation of `wcsncat`: The behavior is undefined if the destination array is not large enough for the contents of both str and dest and the terminating null wide character. `wcsncat` does not allocate memory, it expects you to provide a sufficiently large mutable buffer. For example, like this: ```d // ... auto cls = new wchar_t[256]; cls[] = 0; cls[0..10] = 'A'; wchar_t* clang_string = cls.ptr; // ... ``` That is correct, the results are satisfying. I believe this thread is resolved. ``` import std.stdio; @system void main(){ import std.utf: toUTF16z, toUTF16; import core.stdc.wchar_ : wcsncat, wcslen, wprintf; import core.stdc.stdlib : wchar_t; import core.sys.windows.winnt : LPCWSTR; auto cls = new wchar_t[256]; cls[] = 0; cls[0..10] = 'A'; wchar_t* clang_string = cls.ptr; //wchar_t* clang_string = cast(wchar_t *)"AA"; wstring dlang_string = "BB"w; //< NEW, same results LPCWSTR winpointer_to_string = "CC"; wcsncat(clang_string, dlang_string.toUTF16z, wcslen(dlang_string.toUTF16z)); // String output: AABB wcsncat(clang_string, winpointer_to_string, wcslen(winpointer_to_string)); // String output: AABBCC // Expected string: AABBCC wprintf(clang_string); // String output: AABBCC // Expected string: AABBCC } ```
Re: Looking for a workaround
On Wednesday, 6 April 2022 at 18:10:32 UTC, Guillaume Piolat wrote: Any idea how to workaround that? I really need the same UDA in parent and child class. Use a frontend >= dmd 2.099, it works according to run.dlang.io.
Re: A weird example of .toUTF16z concatination side-effects in wcsncat
On Thursday, 7 April 2022 at 10:50:35 UTC, BoQsc wrote: wchar_t* clang_string = cast(wchar_t *)"AA"; You're witnessing undefined behavior. "AA" is a string literal and is stored in the data segment. Mere cast to wchar_t* does not make writing through that pointer legal. Moreover, even if it was legal to write through it, that alone wouldn't be sufficient. From documentation of `wcsncat`: The behavior is undefined if the destination array is not large enough for the contents of both str and dest and the terminating null wide character. `wcsncat` does not allocate memory, it expects you to provide a sufficiently large mutable buffer. For example, like this: ```d // ... auto cls = new wchar_t[256]; cls[] = 0; cls[0..10] = 'A'; wchar_t* clang_string = cls.ptr; // ... ```
Re: A weird example of .toUTF16z concatination side-effects in wcsncat
On Thursday, 7 April 2022 at 11:03:39 UTC, Tejas wrote: On Thursday, 7 April 2022 at 10:50:35 UTC, BoQsc wrote: Here I try to concatenate three character strings using `wcsncat()`. [...] Maybe try using `wstring` instead of string? Also use the `w` postfix ```d wstring dlang_string = "BBB"w; I can't test because I'm not on my PC and I don't use Windows Exactly same results. `AA` ``` import std.stdio; @system void main(){ import std.utf: toUTF16z, toUTF16; import core.stdc.wchar_ : wcsncat, wcslen, wprintf; import core.stdc.stdlib : wchar_t; import core.sys.windows.winnt : LPCWSTR; wchar_t* clang_string = cast(wchar_t *)"AA"; wstring dlang_string = "BBB"w; //< NEW, same results LPCWSTR winpointer_to_string = "CC"; wcsncat(clang_string, dlang_string.toUTF16z, wcslen(dlang_string.toUTF16z)); // String output: AABBB wcsncat(clang_string, winpointer_to_string, wcslen(winpointer_to_string)); // String output: AA // Expected string: AABBBCC wprintf(clang_string); // String output: AA // Expected string: AABBBCC } ```
Re: A weird example of .toUTF16z concatination side-effects in wcsncat
On Thursday, 7 April 2022 at 10:50:35 UTC, BoQsc wrote: Here I try to concatenate three character strings using `wcsncat()`. [...] Maybe try using `wstring` instead of string? Also use the `w` postfix ```d wstring dlang_string = "BBB"w; I can't test because I'm not on my PC and I don't use Windows
A weird example of .toUTF16z concatination side-effects in wcsncat
Here I try to concatenate three character strings using `wcsncat()`. `clang_string` AA `dlang_string` BBB `winpointer_to_string` CC ``` import std.stdio; @system void main(){ import std.utf: toUTF16z, toUTF16; import core.stdc.wchar_ : wcsncat, wcslen, wprintf; import core.stdc.stdlib : wchar_t; import core.sys.windows.winnt : LPCWSTR; wchar_t* clang_string = cast(wchar_t *)"AA"; string dlang_string = "BBB"; LPCWSTR winpointer_to_string = "CC"; wcsncat(clang_string, dlang_string.toUTF16z, wcslen(dlang_string.toUTF16z)); // String output: AABBB wcsncat(clang_string, winpointer_to_string, wcslen(winpointer_to_string)); // String output: AA // Expected string: AABBBCC wprintf(clang_string); // String output: AA // Expected string: AABBBCC } ``` **Problem:** Any *following concatenated string* after "`wcsncat()` concatenation of `dlang_string.toUTF16z` string", happen to not be printed and gets overwritten. **The Expected output:** I was expecting the `wprintf()` **result** to be `AABBBCC` The `wprintf() ` **result** I've received is this: `AA`
Re: Conversion from ANSI 1252 to unicode
On Thursday, 7 April 2022 at 07:24:03 UTC, Johann wrote: Hi all, anybody knows if there are functions (preferably) in Phobos, that translate from unicode to other encodings and vice versa? Johann https://dlang.org/phobos/std_encoding.html
Conversion from ANSI 1252 to unicode
Hi all, anybody knows if there are functions (preferably) in Phobos, that translate from unicode to other encodings and vice versa? Johann