Re: Get function argument name?
`printName(alias var)()` is not a great solution, eg: doesn't work with expressions, doesn't work with variadics, introduces template bloat. https://github.com/dlang/dmd/pull/7821 introduces __traits(getCallerSource, symbol) which will allow what you want. On Sun, Mar 4, 2018 at 1:53 PM, bauss via Digitalmars-d-learn wrote: > On Sunday, 4 March 2018 at 21:48:53 UTC, JN wrote: >> >> On Sunday, 4 March 2018 at 21:12:44 UTC, arturg wrote: >>> >>> >>> you can pass it by alias: >>> >>> import std.stdio; >>> >>> void main(string[] args) >>> { >>> int x; >>> printName!(x); >>> } >>> >>> void printName(alias var)() >>> { >>> writeln(__traits(identifier, var), " ", var); >>> } >> >> >> Well, it works. But I am confused now, why. Isn't alias only for types >> (like a typedef)? Why can we use it for variable here? > > > Because it is what it is, an alias. Not a type. > > It can be a type, expression or member/variable.
Re: Tuts/Aritcles: Incrementasl C++-to-D conversion?
also related: https://github.com/Syniurge/Calypso/issues/85 (feasibility of extending calypso to do source to source translation (eg C++ => D or C=>D) ) On Thu, Feb 22, 2018 at 12:43 AM, ketmar via Digitalmars-d-learn wrote: > Nick Sabalausky (Abscissa) wrote: > >> Are there any tutorials or articles out there for "getting started with >> converting a C++ codebase to D one module at a time?" Or at the very least: >> tips, tricks, lessions learned, from those who have come before. > > > from my experience (various codebases up to middle size, mostly C, some > C++): fsck the "one module at a time" idea! even in D modules are > interwined, and in C and C++ they're even more so. besides, converting tests > is tedious, it is much funnier to have something working. > > so, i'm usually converting alot of code, up to the whole codebase. it is not > fun when compler spits 100500 errors, but when it finally stops... oh, joy! > > trick: use 'sed' (or your favorite regexp search-and-replace tool) alot. > basically, before HDD crash i almost had a set of scripts that does 80-90 > percents of work translating C to D with sed. ;-) then use editor with "jump > to error line" support, and simply compile your code, fixing errors one by > one. > > tip: try to not rewrite code in any way until it works. i know how tempting > it to replace "just this tiny thing, it is so ugly, and in D we have a nice > idiom!" NEVAR. this is by far the most important thing to remember (at least > for me), so i'll repeat it again: no code modifications until it works! > > personal memories: C code often using things like `a == &arr[idx]`, where > idx can go just past the last array element. it got me when i was doing enet > conversion. nasty trick. > > otherwise, sweat and blood, and patience.
Re: what's the point of function template declarations if they can't be defined?
makes sense to show these (version X11), but that could be done using dmd and a special flag instead of having to rely on a new parser (which would need to be kept updated) On Thu, Feb 8, 2018 at 6:49 AM, Adam D. Ruppe via Digitalmars-d-learn wrote: > On Thursday, 8 February 2018 at 09:42:08 UTC, Timothee Cour wrote: >> >> I guess you mean `version(StdDdoc)` ? >> >> On that note, I see things like this, which are not DRY: > > > This is actually one of the reasons why I abandoned dmd for my dpldocs.info > fork and used an independent parser. > > dmd tries to build docs as it builds the program, but these are slightly > contradictory - when building the program, you need to honor versioned out > blocks. When building the docs, you just want it documented, not ignored. > dmd is (rightfully) prioritized toward building actual code, but that leaves > doc generation a bit second-hand. > > To work around dmd's clashing goals, version(StdDdoc) manually makes a > separate doc branch. > > Whereas my doc generator just shows them all, bringing the version into the > definition. > http://dpldocs.info/experimental-docs/arsd.simpledisplay.XDisplayConnection.html >
Re: are scope guards (scope(exit, success, failure)) zero-cost abstractions?
I know that, my question is whether it adds any runtime overhead over naive way (which is to call the "bar" finalizer before each return statement) in the case where no exception is thrown On Thu, Feb 8, 2018 at 2:44 AM, Mike Parker via Digitalmars-d-learn wrote: > On Thursday, 8 February 2018 at 10:09:12 UTC, Timothee Cour wrote: >> >> I'm curious whether scope guards add any cost over the naive way, eg: >> >> ``` >> void fun(){ >> ... >> scope(success) {bar;} >> ... >> } >> ``` >> >> vs: >> >> ``` >> void fun(){ >> ... >> if(foo1){ >> bar; // add this before each return >> return; >> } >> ... >> bar; >> return; >> } >> ``` >> >> For scope(success) and scope(failure), the naive way would anyway >> involve try/catch statements but what about scope(exit)? Does the >> zero-cost exception model (zero cost being for non-thrown exceptions) >> guarantee us that scope(success) has 0 overhead over naive way? > > > Scope guards are lowered to the equivalent try/catch/finally blocks anyway.
Re: are scope guards (scope(exit, success, failure)) zero-cost abstractions?
likewise, will scope(exit) add any overhead over naive code in the case where no exception is thrown? ``` void fun(){ ... scope(success) {bar;} ... } vs void fun(){ ... if(foo1){ bar; // add this before each return return; } ... bar; return; } ``` On Thu, Feb 8, 2018 at 2:09 AM, Timothee Cour wrote: > I'm curious whether scope guards add any cost over the naive way, eg: > > ``` > void fun(){ > ... > scope(success) {bar;} > ... > } > ``` > > vs: > > ``` > void fun(){ > ... > if(foo1){ > bar; // add this before each return > return; > } > ... > bar; > return; > } > ``` > > For scope(success) and scope(failure), the naive way would anyway > involve try/catch statements but what about scope(exit)? Does the > zero-cost exception model (zero cost being for non-thrown exceptions) > guarantee us that scope(success) has 0 overhead over naive way?
are scope guards (scope(exit, success, failure)) zero-cost abstractions?
I'm curious whether scope guards add any cost over the naive way, eg: ``` void fun(){ ... scope(success) {bar;} ... } ``` vs: ``` void fun(){ ... if(foo1){ bar; // add this before each return return; } ... bar; return; } ``` For scope(success) and scope(failure), the naive way would anyway involve try/catch statements but what about scope(exit)? Does the zero-cost exception model (zero cost being for non-thrown exceptions) guarantee us that scope(success) has 0 overhead over naive way?
Re: what's the point of function template declarations if they can't be defined?
> It's been my understanding that it's always been illegal to provide a definition for a function that was declared previously unless it was declared in a .di file Compiler has always allowed that: ``` void fun(); void fun(){} ``` (but see details in bug report) > It's useful with stuff like version(Ddoc). I guess you mean `version(StdDdoc)` ? On that note, I see things like this, which are not DRY: ``` version(StdDdoc) string readLink(R)(R link) if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) || isConvertibleToString!R); else version(Posix) string readLink(R)(R link) if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) || isConvertibleToString!R) ``` Is this pattern used because we want to build DDoc on a not-necessarily Posix system (ie to get a DDoc regardless of which environment)? If so, it seems like an anti-pattern; better options could be: * build platform specific documentation (which actually makes sense, eg a windows user may not want to see Posix-only functions) * add a special compiler flag that overrides predefined builtins (eg Posix) On Wed, Feb 7, 2018 at 11:21 PM, Jonathan M Davis via Digitalmars-d-learn wrote: > On Wednesday, February 07, 2018 13:39:55 Timothee Cour via Digitalmars-d- > learn wrote: >> ``` >> void fun_bad3(T)(T a); // declaration [1] >> void fun_bad3(T)(T a){}; // definition [2] >> void test(){ >> fun_bad3(1); >> } >> ``` >> Error: test_all.fun_bad3 called with argument types (int) matches both: >> main.d(11): test_all.fun_bad3!int.fun_bad3(int a) >> and: >> main.d(12): test_all.fun_bad3!int.fun_bad3(int a) >> >> should [1] be allowed? > > It's useful with stuff like version(Ddoc). > >> compler doens't allow defining it afterwards in >> [2] (unlike function definitions, and, well, modulo this regression >> https://issues.dlang.org/show_bug.cgi?id=18393) > > It's been my understanding that it's always been illegal to provide a > definition for a function that was declared previously unless it was > declared in a .di file, in which case, you're not really both declaring and > defining it, but the .d file is used when the module is compiled, and the > .di file is used by other modules which use that module, so the declaration > and definition are not seen by the same run of the compiler. > > - Jonathan M Davis >
what's the point of function template declarations if they can't be defined?
``` void fun_bad3(T)(T a); // declaration [1] void fun_bad3(T)(T a){}; // definition [2] void test(){ fun_bad3(1); } ``` Error: test_all.fun_bad3 called with argument types (int) matches both: main.d(11): test_all.fun_bad3!int.fun_bad3(int a) and: main.d(12): test_all.fun_bad3!int.fun_bad3(int a) should [1] be allowed? compler doens't allow defining it afterwards in [2] (unlike function definitions, and, well, modulo this regression https://issues.dlang.org/show_bug.cgi?id=18393)
Re: dirEntries returns relative, not absolute paths
https://github.com/dlang/phobos/pull/6133 On Tue, Feb 6, 2018 at 1:40 PM, Jonathan M Davis via Digitalmars-d-learn wrote: > On Tuesday, February 06, 2018 18:58:43 number via Digitalmars-d-learn wrote: >> https://dlang.org/phobos/std_file.html#dirEntries >> >> >> The name of each iterated directory entry contains the >> >> absolute path. >> >> it seems to be absolute only if the specified path is absolute, >> or always relative to the parent dir of the specified path. > > Then the docs need to be fixed. > > - Jonathan M Davis >
Re: Interfacing with C++
https://github.com/opencv/opencv/issues/6585#issuecomment-221842441 snip: > "C-API" is not supported and should be removed totally (but we have a lack of > resources to port this legacy C code to C++, so some of this code still > exists right now). Also huge part of fresh OpenCV functionality is missing in > "C-API". There is no plan to fix this in OpenCV directly. http://answers.opencv.org/question/17546/opencv-will-drop-c-api-support-soon/ snip: > Shervin is right, the C API is not developed for a long time. All the new > stuff has the C++ API, and it is not backported to the C. So, C API becomes > obsolete and causes pain in the neck, since it should be maintained I recommend trying out Calypso and helping ironing out any bugs you may find. On Mon, Feb 5, 2018 at 3:15 AM, Kagamin via Digitalmars-d-learn wrote: > On Sunday, 4 February 2018 at 08:33:20 UTC, Mike Parker wrote: >> >> Though, I'm curious why anyone would want to declare a callback in a C++ >> program as cdecl only on Windows and use the default C++ convention >> everywhere else. I suggest you dig into it and make sure that's what's >> intended. And good luck binding to OpenCV! >> >> >> [1] >> https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core/types_c.h#L68 > > > No, it's C everywhere, see > https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core/types_c.h#L1774
Re: Interfacing with C++
Calypso (https://github.com/Syniurge/Calypso/) is the most promising way to interface with C++, it requires 0 bindings and understands all of C++ (templates etc); there are some caveats/kinks that are being ironed out (and any help is welcome). On Sun, Feb 4, 2018 at 4:37 AM, rjframe via Digitalmars-d-learn wrote: > On Sun, 04 Feb 2018 08:33:20 +, Mike Parker wrote: > >> Though, I'm curious why anyone would want to declare a callback in a C++ >> program as cdecl only on Windows and use the default C++ >> convention everywhere else. I suggest you dig into it and make sure >> that's what's intended. And good luck binding to OpenCV! > > My guess would be that it's to prevent name mangling of functions in a > generated DLL and the need for a DEF file.
Re: C++ Interop
see also https://github.com/Syniurge/Calypso/ although I'm having lots of issues using it on OSX On Fri, Jan 5, 2018 at 9:02 AM, qznc via Digitalmars-d-learn wrote: > I'm exploring [0] C++ interop after watching Walter's presentation [1]. > > I hit a block with classes as template parameters. This means vector > works, but vector does not. D seems to map vector!Foo to vector. > Likewise shared_ptr is a problem. Any way to fix that on the D side? > The ugly workaround is to adapt the C++ code. > > I understand that this mapping makes sense for function calls because > bar(Foo f) in D maps to bar(Foo *f) in C++. And C++ bar(Foo f) has no > equivalent in D because classes are reference types. > > On a related note, C++ interop requires to redeclare or even reimplement C++ > code. Has anybody started a libcpp-in-d project? I'm looking for basics like > vector and string. > > [0] https://github.com/qznc/d-cpptest > [1] https://youtu.be/IkwaV6k6BmM
why does unittest mangled name now contains full file path instead of fully qualified module name?
why does unittest mangled name now contains full file path instead of fully qualified module name? seems like a regression, previous behavior seemed better and not dependent on installation path.
Re: Application settings
I use protocol buffers (using dproto) for this, storing my settings in either text or wire format. Advantages: type-safety with fwd/backward compatibility (unlike json which requires dynamic field access, eg with dproto you get errors at compile time instead of runtime), supports comments (although can be done w preprocessor on json config file), supports more types than json (especially binary without needing to base64 encode). On Sat, Jul 8, 2017 at 11:35 AM, Seb via Digitalmars-d-learn wrote: > On Saturday, 8 July 2017 at 05:00:45 UTC, bauss wrote: >> >> On Friday, 7 July 2017 at 22:52:22 UTC, FoxyBrown wrote: >>> >>> On Friday, 7 July 2017 at 20:45:36 UTC, Moritz Maxeiner wrote: On Friday, 7 July 2017 at 19:40:35 UTC, FoxyBrown wrote: > > [...] "best" always depends on your specific use case. I use json files via asdf [1] [1] https://github.com/tamediadigital/asdf >>> >>> >>> >>> Seems like quite a heavy package for what I need. I just want to write a >>> AA to disk and load it, ultimately. >> >> >> Then I would go with INI, because you'll ultimately just have key-value >> pairs. >> >> https://code.dlang.org/packages/baussini (Pretty old but should still work >> just fine.) > > > There is also inifiled: https://github.com/burner/inifiled (used for > Dscanner for example)
Re: D equivalent of C++11's function local static initialization?
NOTE: curious about both cases: * thread local * shared On Tue, May 16, 2017 at 8:04 PM, Timothee Cour wrote: > what's the best D equivalent of C++11's function local static initialization? > ``` > void fun(){ > static auto a=[](){ > //some code >return some_var; > } > } > ``` > > (C++11 guarantees thread safety)
D equivalent of C++11's function local static initialization?
what's the best D equivalent of C++11's function local static initialization? ``` void fun(){ static auto a=[](){ //some code return some_var; } } ``` (C++11 guarantees thread safety)
Error: unrecognized switch '--DRT-oncycle=print' => where is switch defined?
Getting this: ``` Deprecation 16211 warning: A cycle has been detected in your program that was undetected prior to DMD 2.072. This program will continue, but will not operate when using DMD 2.073 to compile. Use runtime option --DRT-oncycle=print to see the cycle details. ``` Where is ` --DRT-oncycle=print` defined? can't find it even on DMD64 D Compiler v2.075.0-devel-c3ddfaa-dirty And adding the switch results in: Error: unrecognized switch '--DRT-oncycle=print'
Re: pointer not aligned
indeed. NOTE: ldmd2/ldc2 doens't have this issue to reproduce: ``` rdmd --force --eval='writeln(`hello`)' ``` ld: warning: pointer not aligned at address 0x1000BE0B9 (_D53TypeInfo_S3std5array17__T8AppenderTAyaZ8Appender4Data6__initZ + 24 from .rdmd-501/rdmd-eval.o) with `--compiler=ldmd2` there's no error On Fri, Mar 31, 2017 at 2:06 AM, Adam Wilson via Digitalmars-d-learn wrote: > On 3/30/17 10:47 PM, H. S. Teoh via Digitalmars-d-learn wrote: >> >> On Fri, Mar 31, 2017 at 04:41:10AM +, Joel via Digitalmars-d-learn >> wrote: >>> >>> Linking... >>> ld: warning: pointer not aligned at address 0x10017A4C9 >>> (_D30TypeInfo_AxS3std4file8DirEntry6__initZ + 16 from >>> .dub/build/application-debug-posix.osx-x86_64-dmd_2072-EFDCDF4D45F944F7A9B1AEA5C32F81ED/spellit.o) >>> ... >>> >>> and this goes on forever! >> >> >> More information, please. What was the code you were trying to compile? >> What compile flags did you use? Which compiler? >> >> >> T >> > > I see this on OSX as well. Any code referencing Phobos appears to produce > this. It appear after updating the XCode command line tools. It does not > appear to effect program execution, but the pages of warnings are really > quite annoying. > > DMD 2.073.2 > > -- > Adam Wilson > IRC: LightBender > import quiet.dlang.dev;
Re: Strange Bug
This and some other recent posts (`Is this a bug?`, `Hopefully a simple question...`). If you want help (and help other ppl who search for similar issues), could you please make the subject more descriptive? On Fri, Jan 20, 2017 at 12:19 AM, Chris M. via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > I have no idea if this is an issue with D, or OpenSSL, or if I'm just > doing something completely wrong. I'm writing a program that will either > encrypt or decrypt a string using AES in ECB mode (for a school assignment) > and it's giving me a very strange bug. > > encrypt and decrypt are both bools, either one or the other is set based > on command-line arguments passed to the program. aesKey is a 128-bit value > hashed from user input, and is (obviously) used as the key for encryption. > inputStr is either the string to be encrypted or decrypted (also passed in > as a command-line argument). I grabbed the OpenSSL bindings from Deimos to > do this. > > if(encrypt) > { > AES_KEY encKey; > auto encOut = new ubyte[inputStr.length]; > > // Encrypt and convert to base64 > AES_set_encrypt_key(aesKey.ptr, aesKey.sizeof * 8, &encKey); > AES_ecb_encrypt(inputStr.ptr, encOut.ptr, &encKey, AES_ENCRYPT); > writeln(Base64.encode(encOut)); > } > else if(decrypt) // I'd leave this as else, but it's here for explanation > purposes > { > AES_KEY decKey; > auto decLength = Base64.decodeLength(inputStr.length); > auto decB64 = new ubyte[decLength], decOut = new ubyte[decLength]; > > // convert back from base64 and decrypt > decB64 = Base64.decode(inputStr); // Yes I checked, and decB64 has > exact the same contents as encOut from the if block > AES_set_decrypt_key(aesKey.ptr, aesKey.sizeof * 8, &decKey); > AES_ecb_encrypt(decB64.ptr, decOut.ptr, &decKey, AES_DECRYPT); > writeln(cast(char[]) decOut); > } > > However, this isn't working for a very strange reason (spits back garbage > instead of the string I originally encrypted). > > Here's the problem. I tried running this without the if-else statements > (i.e. encrypting and decrypting all in one run of the program, code below). > If I leave in the base64 encoding and decoding, and use decB64 as the input > to decrypt, it still doesn't work. However, if I decrypt with encOut > directly, or assign encOut to decB64, it somehow works. > > AES_KEY encKey; > auto encOut = new ubyte[inputStr.length]; > > // Encrypt and convert to base64 > AES_set_encrypt_key(aesKey.ptr, aesKey.sizeof * 8, &encKey); > AES_ecb_encrypt(inputStr.ptr, encOut.ptr, &encKey, AES_ENCRYPT); > > auto decLength = Base64.decodeLength(Base64.encode(encOut).length); > AES_KEY decKey; > auto decB64 = new ubyte[decLength], decOut = new ubyte[decLength]; > > // convert back from base64 and decrypt > decB64 = Base64.decode(Base64.encode(encOut)); > // doesn't work unless I uncomment out the following line, or just use > encOut directly > //decB64 = encOut; > AES_set_decrypt_key(aesKey.ptr, aesKey.sizeof * 8, &decKey); > AES_ecb_encrypt(decB64.ptr, decOut.ptr, &decKey, AES_DECRYPT); > writeln(cast(char[]) decOut); > > tl;dr The decryption doesn't work unless I pass it the exact same buffer > (including not only contents, but apparently the exact same memory address) > that I used to receive output from encryption > > Does anyone have any idea where the issue may lie, or how I could fix this? > > Here's the full program if you want to take a look > http://pastebin.com/KyY103Ac >
DRY version of `static if(__traits(compiles, expr)) fun(expr)`
what's the best (and DRY) way to achieve: ``` static if(__traits(compiles, expr)) fun(expr); ``` ie, without repeating the expression inside expr? eg: ``` static if(__traits(compiles, foo.bar[2])){ counter++; writeln(" expr = ", foo.bar[2]); } ```
Re: [Semi-OT] I don't want to leave this language!
My 2 cents: for most applications, hotspots tend to be in a tiny percentage of the code (ie 90/10 rule where 10% of code accounts for 90% execution time, although my experience in large projects is even more unbalanced) ; throwing away druntime or GC for the whole codebase based on performance concerns amounts to (evil) early optimization. It's far more productive to use a profiler and carefully optimize only the parts that need to be (possibly using betterc, @nogc, ldc and optimized compiler flags for those hotspots only). What could be done better would be to remove friction when linking in shared objects produced by dmd and ldc (eg, extern(D) functions have different number of underscores in dmd vs ldc). On that note, even if dmd is 50x slower than ldc for certain blas mir routines, it's still valuable to have mir supported by dmd as we can always swap in the slow parts during production runs, but we'd benefit with fast compile time during development time, On Tue, Dec 6, 2016 at 3:08 PM, aberba via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > On Tuesday, 6 December 2016 at 22:13:54 UTC, bpr wrote: > >> On Tuesday, 6 December 2016 at 17:00:35 UTC, Jonathan M Davis >> > > I would guess that the vast majority of interest shown in Rust is from >> people who essentially want a better C or C++, with no runtime/GC. So, I >> think Ilya's point is very plausible. D with no GC, but with modules, >> templates, overloading, CTFE, and some other features might have been more >> tempting to the no-GC crowd, which includes many hardcore C++ programmers. >> >> Those programmers who are comfortable working in a GC-ed language will >> likely eschew D because D's GC is really not that great. >> > > > I don't really get the issue with D's GC, Phobos and DRuntime. JavaScript > is really popular and getting really popular everyday (I mean Nodejs). Same > as Python, PHP, Ruby (startups), etc. But they are not exactly betterC. > Most of them don't even give native code speed. > > When using D, I just want to get my app working and running. That is why > more packages (vibe.d, mail, request, mysql-lited, etc) matter to me. The > level you are trying to raise D is way over-kill IMO :). It's good though > for those who need it. But most of us don't judge languages that way. >
extern(C++) with template produces wrong mangleof
What's the difference bw _Z21test_D20161202T141925IiET_S0_ and _Z21test_D20161202T141925IiEii? mangleof produces the one that's not in the library produced: test.cpp: ``` template T test_D20161202T141925(T a); template int test_D20161202T141925(int); ``` clang++ -shared -o libtest.so test.cpp c++filt _Z21test_D20161202T141925IiET_S0_ int test_D20161202T141925(int) c++filt _Z21test_D20161202T141925IiEii int test_D20161202T141925(int) nm libtest.so|grep test_D20161202T141925: 0ae0 W _Z21test_D20161202T141925IiET_S0_ ``` test.d: ``` extern(C++){ void test_D20161202T141743(); T test_D20161202T141925(T)(T a); } void test(){ assert(test_D20161202T141925!int.mangleof == "_Z21test_D20161202T141925IiEii"); // but I would expect _Z21test_D20161202T141925IiET_S0_ (otherwise, undefined symbol) } ```
The module 'foo' is already defined in 'libmylib.so'
I want to update a library with new symbols (ie partial recompilation): libmylib.so : compiled from bar.d and foo.d now update the file foo.d dmd -c -fPIC foo.d -offoo.o clang++ -o libmylib_update.so foo.o -shared -Wl,-lmylib When trying to dlopen libmylib_update.so from C++ it fails with: The module 'foo' is already defined in 'libmylib.so' (it somehow works when the dlopen is called from D) How would I achieve that?
how to catch D Throwables (or exceptions) from C++?
eg: ``` dlib.d: extern(C) void dfun(){assert(0, "some_msg");} clib.cpp: extern "C" void dfun(); void fun(){ try{ dfun(); } catch(...){ // works but how do i get "some_msg" thrown from D? } } ```
Re: how to debug exceptions/asserts thrown in module constructors?
UPDATE: * b Loader.d:123 didn't help either: error: parsing line table prologue at 0x (parsing ended around 0x Breakpoint 1: where = mybinary.temp`D4gtkc6Loader6Linker12_staticDtor3FZv, address = 0x000100315410 (process exited despite breakpoint); dmd's dwarf debug info seems incorrect * b _d_throwc #does nothing * b _d_print_throwable: doesn't show useful context (only shows backtrace after stack unwinding) (lldb) bt * thread #1: tid = 0x6187c1, 0x000100191c30 mybinary.temp _d_print_throwable, stop reason = breakpoint 4.1 * frame #0: 0x000100191c30 mybinary.temp _d_print_throwable frame #1: 0x000100191530 mybinary.temp rt_init + 160 frame #2: 0x000100191a9a mybinary.temp D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv + 14 frame #3: 0x000100191a40 mybinary.temp D2rt6dmain211_d_run_ mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 36 frame #4: 0x0001001919a6 mybinary.temp _d_run_main + 498 frame #5: 0x00011efa mybinary.temp main + 34 frame #6: 0x7fff89ad65ad libdyld.dylib start + 1 * b _D4gtkc6Loader6Linker11loadLibraryFAyaZv isn't very helpful since this function is complex (and could be inlined more generally) and that function is called many times before the exception is thrown ``` public static void loadLibrary(string library) { void* handle = pLoadLibrary(library); //TODO: A more general way to try more than one version. if ( handle is null && library == importLibs[LIBRARY.GSV] ) handle = pLoadLibrary(importLibs[LIBRARY.GSV1]); if ( handle is null ) throw new Exception("Library load failed: " ~ library); loadedLibraries[library] = handle; } ``` but at least we get a better context: (lldb) bt * thread #1: tid = 0x6187c1, 0x000100315878 mybinary.temp D4gtkc6Loader6Linker11loadLibraryFAyaZv, stop reason = breakpoint 3.1 * frame #0: 0x000100315878 mybinary.temp D4gtkc6Loader6Linker11loadLibraryFAyaZv frame #1: 0x000100315699 mybinary.temp D4gtkc6Loader6Linker9getSymbolFAyaAAyaXPv + 237 frame #2: 0x0001003155a4 mybinary.temp D4gtkc6Loader6Linker9getSymbolFAyaAE4gtkc5paths7LIBRARYXPv + 232 frame #3: 0x0001003163bd mybinary.temp D4gtkc6Loader6Linker39__ T4linkTPUZE4gtkc12gobjecttypes5GTypeZ4linkFKPUZE4gtkc12gobje cttypes5GTypeAyaAE4gtkc5paths7LIBRARYXv + 69 at .dub/packages/gtk-d-3.3.1/gtk-d/src/gtkc/Loader.d:46 frame #4: 0x00010038c75d mybinary.temp D4gtkc3atk18_sharedStaticCtor4FZv + 77 at .dub/packages/gtk-d-3.3.1/gtk-d/src/gtkc/atk.d:36 frame #5: 0x00010038c67d mybinary.temp _D4gtkc3atk15__modsharedctorFZv + 9 at .dub/packages/gtk-d-3.3.1/gtk-d/src/gtkc/atk.d:32 frame #6: 0x000100199c17 mybinary.temp D2rt5minfo67__ T14runModuleFuncsS442rt5minfo11ModuleGroup8runCtorsMFZ9__ lambda2Z14runModuleFuncsMFAxPyS6object10ModuleInfoZv + 91 frame #7: 0x000100199785 mybinary.temp D2rt5minfo11ModuleGroup8runCtorsMFZv + 37 frame #8: 0x000100199a91 mybinary.temp D2rt5minfo13rt_moduleCtorUZ14__foreachbody1MFKS2rt19sections_osx_x86_6412SectionGroupZi + 45 frame #9: 0x000100199a60 mybinary.temp rt_moduleCtor + 20 frame #10: 0x0001001914f3 mybinary.temp rt_init + 99 frame #11: 0x000100191a9a mybinary.temp D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv + 14 frame #12: 0x000100191a40 mybinary.temp D2rt6dmain211_d_run_ mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 36 frame #13: 0x0001001919a6 mybinary.temp _d_run_main + 498 frame #14: 0x00011efa mybinary.temp main + 34 frame #15: 0x7fff89ad65ad libdyld.dylib start + 1 Ideally there should be a way (via a runtime or compile time option) to wrap the exception throwing (during rt_moduleCtor) inside a extern(C) function that we can put a breakpoint on (and possibly even call backtrace_symbols on) On Sun, Nov 27, 2016 at 2:19 PM, Timothee Cour wrote: > in the process of trying to debug https://github.com/ > BlackEdder/ggplotd/issues/32 I would like to get a stracktrace and/or put > a breakpoint before exception is thrown: > > > ``` > lldb $binary > r > (lldb) > Process 34168 resuming > object.Exception@../../../../.dub/packages/gtk-d-3.3.1/gtk-d/src/gtkc/Loader.d(123): > Library load failed: libatk-1.0.dylib > Process 34168 exited with status = 1 (0x0001) > ``` > > Adding > ``` > b _d_throwc #does nothing > ``` > > didn't help, also, it hasn't entered d main yet so `Runtime.traceHandler = > &defaultTraceHandler;` isn't helpful. > > The fix here was to lookup the code, find the corresponding mangled name > location and add a breakpoint via `b _D4gtkc6Loader6Linker11loadLibraryFAyaZv` > but is there a general fix? > >
how to debug exceptions/asserts thrown in module constructors?
in the process of trying to debug https://github.com/BlackEdder/ggplotd/issues/32 I would like to get a stracktrace and/or put a breakpoint before exception is thrown: ``` lldb $binary r (lldb) Process 34168 resuming object.Exception@../../../../.dub/packages/gtk-d-3.3.1/gtk-d/src/gtkc/Loader.d(123): Library load failed: libatk-1.0.dylib Process 34168 exited with status = 1 (0x0001) ``` Adding ``` b _d_throwc #does nothing ``` didn't help, also, it hasn't entered d main yet so `Runtime.traceHandler = &defaultTraceHandler;` isn't helpful. The fix here was to lookup the code, find the corresponding mangled name location and add a breakpoint via `b _D4gtkc6Loader6Linker11loadLibraryFAyaZv` but is there a general fix?
mangle!(void function())("foo").demangle = "void function()* foo"
mangle!(void function())("foo").demangle returns "void function()* foo" how would i get instead: `void foo ()` ? my current workaround: alias FunctionTypeOf(Fun)=typeof(*Fun.init); mangle!(FunctionTypeOf!(void function()))("foo")
zip: why isn't requireSameLength the default?
in zip: why isn't requireSameLength the default? This is the most common case and would fit with the goal of being safe by default.
Re: Checking if a port is listening
see also: https://github.com/rejectedsoftware/vibe.d/issues/1431 api to find an available port On Fri, Mar 18, 2016 at 2:50 AM, Marc Schütz via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > Looking at an strace of nmap, it seems it opens a bunch of sockets, puts > them into non-blocking mode, calls connect on them (which will return > EINPROGRESS), and then uses select(2) to wait for them (in a loop, until > all have either been accepted or rejected). select(2) accepts a timeout > value, so you can determine how long you want to wait. > > Here's an excerpt: > > ... > socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 50 > fcntl(50, F_GETFL) = 0x2 (flags O_RDWR) > fcntl(50, F_SETFL, O_RDWR|O_NONBLOCK) = 0 > setsockopt(50, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0 > setsockopt(50, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) = -1 EPERM (Operation > not permitted) > setsockopt(50, SOL_IP, IP_TTL, [-1], 4) = 0 > connect(50, {sa_family=AF_INET, sin_port=htons(32778), > sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in > progress) > socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 51 > fcntl(51, F_GETFL) = 0x2 (flags O_RDWR) > fcntl(51, F_SETFL, O_RDWR|O_NONBLOCK) = 0 > setsockopt(51, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0 > setsockopt(51, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) = -1 EPERM (Operation > not permitted) > setsockopt(51, SOL_IP, IP_TTL, [-1], 4) = 0 > connect(51, {sa_family=AF_INET, sin_port=htons(1029), > sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in > progress) > socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 52 > fcntl(52, F_GETFL) = 0x2 (flags O_RDWR) > fcntl(52, F_SETFL, O_RDWR|O_NONBLOCK) = 0 > setsockopt(52, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0 > setsockopt(52, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) = -1 EPERM (Operation > not permitted) > setsockopt(52, SOL_IP, IP_TTL, [-1], 4) = 0 > connect(52, {sa_family=AF_INET, sin_port=htons(2013), > sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in > progress) > select(53, [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 > 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 > 51 52], [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 > 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 > 52], [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 > 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 > 52], {0, 0}) = 100 (in [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 > 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 > 47 48 49 50 51 52], out [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 > 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 > 47 48 49 50 51 52], left {0, 0}) > ... > > I'm pretty sure the setsockopt() calls aren't essential. >
Re: How to list all version identifiers?
would be easy with compiler as a library... also i thought 'dmd -v -version=foo -c -o- bar.d' would show -version identifiers used on the command line but doesn't seem to On Tue, Mar 15, 2016 at 8:51 AM, Iakh via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > On Sunday, 13 March 2016 at 20:16:36 UTC, Basile B. wrote: > >> On Sunday, 13 March 2016 at 16:28:50 UTC, Iakh wrote: >> >>> On Sunday, 13 March 2016 at 15:50:47 UTC, Basile B. wrote: >>> trivial answer, let's say you have dcd-server running in the background: dcd-client -c8 <<< "version(" >>> >>> Thanks. Will try. >>> >> >> But it was a joke actually. It works but this is not very >> straightforward. And it needs a bit of post processing since the output >> you'll get is normally made for the completion menu of D editors. >> > > Looks like it shows all version identifiers listed in > https://dlang.org/spec/version.html#version > and it's not what I want. I need just actual ones under some > compiler/circumstances >
get stacktrace across all threads
It would be nice to have an api to get stacktrace across threads; it would be particularly useful for server applications (eg vibe.d). Has anyone implemented something similar? I guess one would need to use signal handlers to interrupt each thread?
Re: Scale-Hierarchy on ndslice
On Wed, Jan 13, 2016 at 10:13 AM, jmh530 via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > On Tuesday, 12 January 2016 at 21:48:39 UTC, Per Nordlöw wrote: > >> Have anybody been thinking about adding a scale-hierarchy structure on >> top of ndslice? >> > > What is a scale-hierarchy structure? > https://en.wikipedia.org/wiki/Mipmap but isn't it out of scope? Looks like it would belong more to an image processing library (building on top of ndslice)
Re: to!string(double) at compile time
On Thursday, 23 August 2012 at 13:56:05 UTC, Philippe Sigaud wrote: On Tue, Aug 21, 2012 at 6:43 AM, Bobby Bingham wrote: [...] [...] A possibility is to use a function template, passing the double as a template argument: string test(double d)() // d is a template argument { return d.stringof; } enum testvar = mixin(test!(3.14)); void main() { pragma(msg, testvar); } https://issues.dlang.org/show_bug.cgi?id=15497
Re: DMD Compiler 'switches'
On Mon, Oct 12, 2015 at 11:33 AM, ric maicle via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > On Tuesday, 13 October, 2015 01:46 AM, anonymous wrote: > >> On Monday 12 October 2015 17:38, ric maicle wrote: >> >> I'm wondering if this small irregularity should be made consistent or >>> maybe I misunderstood something. >>> >> >> As far as I know, the difference just happened, and there is point to it. >> The style without "=" is older and wasn't followed when new switches were >> added. >> >> Consistency between different switches has to be weighed against stability >> here. So far stability has won, I guess. >> > > I think you made it clearer now. And changing it in minor releases will > break build scripts. 'Deprecating' command line switches may be an option > and possibly better addressed in a major release. > > Also, someone may have already filed an issue about this. > Ya I did a while ago: "new DIP41: dmd/rdmd command line overhaul." http://forum.dlang.org/thread/mailman.1468.1369129517.4724.digitalmar...@puremagic.com
IFTI with template alias fails in D, works in C++
main.d: -- struct A(T, int D) { this(string ignore){} } alias B(T)=A!(T, 1); void fun1(T)(A!(T,1) a) { } void fun2(T)(B!T a) { } unittest{ auto a=A!(double,1)("a"); assert(is(typeof(a) == B!double)); fun1(a);//ok fun2!double(a);//ok // no IFTI here: //fun2(a);//not ok: //fun2 cannot deduce function from argument types !()(A!(double, 1)), candidates are... } -- C++ works fine here: main.cc: -- template class A { }; template using B = A; template void fun(B a) { } void test(){ Aa; fun(a); } -- I can use a workaround but it makes the code uglier. What's the recommended way around this? Could we support this as in C++?
Re: exclude current directory from search path in dmd ?
https://github.com/D-Programming-Language/dmd/pull/4823 On Sun, Jul 19, 2015 at 10:42 PM, ZombineDev via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > On Monday, 20 July 2015 at 03:33:08 UTC, Timothee Cour wrote: > >> I've attached a reduced use case showing that the solutions proposed in >> this thread do not work, and wrote a local modification to dmd to allow a >> flag -exclude_cwd_from_imports that does work. Would that be acceptable to >> have this in official dmd? >> >> > The best way to find out is to make a Pull Request. If it's hard to > workaround than it's a good candidate for enhancement. >
Re: exclude current directory from search path in dmd ?
I've attached a reduced use case showing that the solutions proposed in this thread do not work, and wrote a local modification to dmd to allow a flag -exclude_cwd_from_imports that does work. Would that be acceptable to have this in official dmd? On Sun, Jul 19, 2015 at 8:07 PM, Timothee Cour wrote: > https://issues.dlang.org/show_bug.cgi?id=14811 > > On Wed, Jun 17, 2015 at 3:22 AM, Liran Zvibel via Digitalmars-d-learn < > digitalmars-d-learn@puremagic.com> wrote: > >> On Monday, 8 June 2015 at 04:08:55 UTC, Adam D. Ruppe wrote: >> >>> The easiest way is to not use search paths, and instead pass all the >>> modules you want compiled to the compiler directly. Then it will look for >>> the module name declaration instead of the directory/filename layout. >>> >> >> I think that this should be an explicit decision to also add -I. to the >> compilation or not. >> >> We (at Weka.IO) have to work extra hard to work around it, and since we >> have a large project with many packages it's impractical to just put >> everything on the command line. >> >> Also -- you WANT imported modules to be imported (and use the .di >> equivalent) instead of being compiled on the command line. >> >> A solution that won't break backwards compatibility and will still make >> sense is have this by default in dmd.conf, and when/if required dmd users >> can just modify their dmd.conf file. >> >> Liran >> > >
Re: exclude current directory from search path in dmd ?
https://issues.dlang.org/show_bug.cgi?id=14811 On Wed, Jun 17, 2015 at 3:22 AM, Liran Zvibel via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > On Monday, 8 June 2015 at 04:08:55 UTC, Adam D. Ruppe wrote: > >> The easiest way is to not use search paths, and instead pass all the >> modules you want compiled to the compiler directly. Then it will look for >> the module name declaration instead of the directory/filename layout. >> > > I think that this should be an explicit decision to also add -I. to the > compilation or not. > > We (at Weka.IO) have to work extra hard to work around it, and since we > have a large project with many packages it's impractical to just put > everything on the command line. > > Also -- you WANT imported modules to be imported (and use the .di > equivalent) instead of being compiled on the command line. > > A solution that won't break backwards compatibility and will still make > sense is have this by default in dmd.conf, and when/if required dmd users > can just modify their dmd.conf file. > > Liran >
Re: generic cast(unshared) ?
Note: should work with any types, eg: shared(T[])* => T[]* etc... On Sun, Jun 28, 2015 at 4:42 PM, Timothee Cour wrote: > How would I cast away shared for a given expression? > I can write it for a specific type but I'd like to have a generic way to > do so. > Also, Unqual doesn't help here. > >
generic cast(unshared) ?
How would I cast away shared for a given expression? I can write it for a specific type but I'd like to have a generic way to do so. Also, Unqual doesn't help here.
Re: string to time conversion (when string contains time but no date)
thanks, missed that! On Sat, Jun 27, 2015 at 2:59 AM, via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > On Saturday, 27 June 2015 at 03:17:49 UTC, Timothee Cour wrote: > >> is there a way to convert a string representing a time (without date) to a >> time, eg: >> >> auto t = "19:03:40.143656"; >> auto a=SysTime.fromTimeString(t); // doesn't exist >> >> >> My current workaround is to append a dummy date before and then calling >> SysTime.fromSimpleString. >> >> Is there a better way? seems needed >> > > Try TimeOfDay's methods: > > http://dlang.org/phobos/std_datetime.html#.TimeOfDay.fromISOString > http://dlang.org/phobos/std_datetime.html#.TimeOfDay.fromISOExtString >
string to time conversion (when string contains time but no date)
is there a way to convert a string representing a time (without date) to a time, eg: auto t = "19:03:40.143656"; auto a=SysTime.fromTimeString(t); // doesn't exist My current workaround is to append a dummy date before and then calling SysTime.fromSimpleString. Is there a better way? seems needed
type of a variable as a mixin-able string?
Suppose I have: import std.range; auto a=iota(complex_expr_returning_3()); I'd like to have a function/trait/template/compiler magic that takes variable a and generates a string that can be mixed in to represent the type of a. The difficulty is that typeid(a).to!string doesn't work for Voldermort types: typeid(a).to!string produces "std.range.iota!(int, int).iota.Result", which is not very useful as it can't be mixed in a program, being a voldemort type, eg: mixin("std.range.iota!(int, int).iota.Result a;"); //compile error However, the compiler could help reduce it to something as simple as possible, eg: "typeof(iota(int.init))" here this would work: mixin("typeof(iota(int.init)) a;"); //works Is it possible to do that in a generic way, such that it hides as much as possible the details of the expression (here, "complex_expr_returning_3()" should be simplified to int.init) Or is there another trick I could use to instantiate a variable with same type as a? NOTE: typeof(a) a2; works even though http://www.drdobbs.com/cpp/voldemort-types-in-d/232901591?pgno=2 says it won't work, "Sorry, that won't work, the compiler will not allow a Voldemort Type to be instantiated outside of its scope " (although that's doesn't help with my original problem)
how come is this legal? 'void fun(int){ }' ?
I understand this is legal for declaration wo definition (void fun(int);) but why allow this: void test(int){} ?
Re: Why is there no named parameter support?
On Mon, Jun 8, 2015 at 11:32 PM, Jonathan M Davis via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > On Monday, June 08, 2015 23:18:50 Timothee Cour via Digitalmars-d-learn > wrote: > > nim has both overloading and named arguments (with reordering and > defaults > > allowed): http://nim-lang.org/docs/tut1.html#procedures-named-arguments > > and it doesn't seem to cause issues. > > > > Is there a document / thread that explains the argument against named > > arguments in more details than 'do not play well together' ? > > Probably not, but Walter was quite adamant when it was discussed at dconf > that it's a disaster to mix named arguments and function overloading in the > same language. Maybe it's not as bad as he thinks it is, but personally, I > think that named arguments are a terrible idea in general, so I'm not about > to try and support a position that tries to bring them into D. > > - Jonathan M Davis > > I'd be very interested in reading more about those reasons beyond FUD. The arguments in favor have been repeated many times over, and the only argument against that I've heard ('overloading and named arguments do not play well together') doesn't seem valid, given the precedent in nim.
Re: Why is there no named parameter support?
nim has both overloading and named arguments (with reordering and defaults allowed): http://nim-lang.org/docs/tut1.html#procedures-named-arguments and it doesn't seem to cause issues. Is there a document / thread that explains the argument against named arguments in more details than 'do not play well together' ? On Mon, Jun 8, 2015 at 10:45 PM, Jonathan M Davis via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > On Monday, June 08, 2015 20:36:05 Yuxuan Shui via Digitalmars-d-learn > wrote: > > Is there any reasons/difficulties for not implementing named > > parameters? > > > > There is clearly a need: > > > > > http://forum.dlang.org/thread/wokfqqbexazcguffw...@forum.dlang.org#post-pxndhoskpjxvnoacajaz:40forum.dlang.org > > Function overloading and named arguments do not play well together, and we > have function overloading, so we're not going to have named arguments. > Walter made that clear at dconf. Now, as Idan pointed out in his reply, > work > has been done implement them via a library solution for those that want to, > so you might get something there, but not in the language itself. > > - Jonathan M Davis > >
Re: exclude current directory from search path in dmd ?
On Mon, Jun 8, 2015 at 12:08 AM, Adam D. Ruppe via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > The easiest way is to not use search paths, and instead pass all the > modules you want compiled to the compiler directly. Then it will look for > the module name declaration instead of the directory/filename layout. > Could you be more specific, perhaps with a command line example? If I understand correctly, what you suggest doesn't bode well with separate compilation. Really, I think the easiest would be a flag to disable including current directory implicitly in search path
Re: exclude current directory from search path in dmd ?
ping? On Sun, Mar 15, 2015 at 10:26 PM, Timothee Cour wrote: > Is there a way to exclude current directory from search path in dmd, so > that the search path is only given by '-I' arguments (+ones from dmd.conf)? > > use case: > > files: > /base/foo.d > /base/bar/foo.d > /base/bar/main.d #contains: import foo.d > > cd /base/bar > dmd -I/base main.d > => I want 'import foo.d' to point to /base/foo.d, not /base/bar/foo.d, > but this is not the case since -I. is implicit in search path > >
attribute alias? eg: asm @my_alias {...} alias my_alias=pure nothrow @trusted @nogc;
Is there a way to alias attributes? alias my_alias=pure nothrow @trusted @nogc; asm @my_alias {...} This came up here: https://github.com/Hackerpilot/libdparse/issues/50 Or at least to do the following in a less ugly way? static if(__VERSION__<2067) enum asm_att=``; else enum asm_att=`pure nothrow @nogc`; //lots of statements like this mixin(`asm `~asm_att~` {... }`);
deserialization: creating a class instance without calling constructor
Can I create an instance of A without calling a constructor? (see below) Use case: for generic deserialiaztion, when the deserialization library encounters a class without default constructor for example (it knows what the fields should be set to, but doesn't know how to construct the object). class A{ int x=2; this(int x){ this.x=x; } } This came up here: https://github.com/msgpack/msgpack-d/issues/54#issuecomment-104136148 I provide some hacky solution for that in that thread but I suspect it's not safe and something is missing.
why does phobos use [0, 5, 8, 9][] instead of [0, 5, 8, 9] in examples?
Eg, code like this in std.algorithm: assert(equal(setSymmetricDifference(a, b), [0, 5, 8, 9][])); why not just: assert(equal(setSymmetricDifference(a, b), [0, 5, 8, 9])); ?
exclude current directory from search path in dmd ?
Is there a way to exclude current directory from search path in dmd, so that the search path is only given by '-I' arguments (+ones from dmd.conf)? use case: files: /base/foo.d /base/bar/foo.d /base/bar/main.d #contains: import foo.d cd /base/bar dmd -I/base main.d => I want 'import foo.d' to point to /base/foo.d, not /base/bar/foo.d, but this is not the case since -I. is implicit in search path
mixin template can't contain statements: workaround?
Why can't we allow mixin templates to contain statements, as is the case for regular mixins? Is there a workaround? here's a dummy example: template mixin Foo{ //some statement, eg: 'return;' } void fun(){ mixin Foo; } Note that I can do this with a regular mixin, but template mixins are cleaner (esp in more complex examples).
boilerplate for constructor
I'm trying to define a boilerplate mixin for class constructor to generate code such as: this(T1 a1, T2 a2){this.a1=a1; this.a2=a2;} The following works, but fails if one field is from a superclass, with an error such as: template instance GenThis!(b, a) GenThis!(b, a) is nested in both B and A. Any suggestion? -- template GenThis(fields...){ import std.typecons; import std.typetuple; import std.conv; private static string fun(){ string a="this("; string b; foreach(i;Iota!(fields.length)) { alias field=fields[i]; auto name=Stringof!field; alias T=typeof(field); if(i>0) a~=", "; a~=T.stringof~" "~name; b~="this."~name~"="~name~"; "; } a~=`){`~b~`}`; return a; } enum GenThis=fun(); } unittest{ class A{ int foo; string bar; mixin(GenThis!(bar, foo)); } auto a=new A("abc",2); assert(a.foo==2 && a.bar=="abc"); }
Re: is struct delete deterministic? (cf used in Unique)
On Sun, Mar 8, 2015 at 4:36 AM, Jonathan M Davis via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > On Sunday, March 08, 2015 04:13:28 Jonathan M Davis via > Digitalmars-d-learn wrote: > > On Saturday, March 07, 2015 17:20:49 Timothee Cour via > Digitalmars-d-learn wrote: > > > To clarify, I'm only asking about a struct allocated via new. > > > Unique!T is wrapped around a struct, but it allocates a struct T via > 'new', > > > so my question still holds: does 'delete t' (where t is a struct > allocated > > > via new) guarantee deterministic destruction? > > > > > > I'm guessing yes, otherwise Unique would be broken, but where is that > > > specified in the docs? > > > And if delete is to be deprecated (according to the docs), what is the > > > correct way to do that (despite fact that Unique relies on delete). > > > > Yes, delete is deterministic. It's basically the same as what you get in > C++ > > except that it's using the GC heap and therefore is not safe. delete is > > supposed to have been deprecated but has not been yet (mostly because no > one > > has gotten around to doing it). > > > > If you're using the GC heap and want to destroy an object, that's what > > destroy is for - but it doesn't free the memory, because that's not safe. > > You can free the memory with core.memory.GC.free, but you have to have > > destroyed the object first, since free just frees memory. But that's just > > duplicating what delete does, so it's still unsafe. > > > > What's generally considered the correct way to deal with manual memory > > management involves allocating using C's malloc, constructing via > emplace, > > and then using destroy and C's free to destroy the object and free its > > memory when you're done. But that's way more of a pain then using new and > > then delete, which is probably part of why some folks still use delete > (in > > the case of Unique though, I expect that it's just because it's been > around > > a while). Hopefully, the standard allocator stuff will make it as simple > as > > using new and delete though - e.g. something like > > > > auto ptr = alloc.make!Myobj(arg1, arg2); > > alloc.free(ptr); > > > > but the standard allocator stuff isn't currently far enough along yet > for us > > to be at that point unfortunately. > > I would point out though that until recently, the GC never ran the > destructors for structs on the heap, because it didn't have the type > information to do it. So, if you did > > auto s = new MyStruct; > > its destructor never ran, even if the GC collected it (which it's not > guaranteed to do with any memory). But I don't know if the destructor was > run if you expliictly called delete on the pointer to the struct. > Thanks for you answers, however this last sentence worries me. According to it there's no guarantee then? > > However, there has recently been work done to make it so that struct > destructors on the heap _are_ run when a struct is collected by the GC, so > the situation there is improving, and if delete didn't call the destructor > before, it probably will with the next release. > > - Jonathan M Davis > >
Re: is struct delete deterministic? (cf used in Unique)
To clarify, I'm only asking about a struct allocated via new. Unique!T is wrapped around a struct, but it allocates a struct T via 'new', so my question still holds: does 'delete t' (where t is a struct allocated via new) guarantee deterministic destruction? I'm guessing yes, otherwise Unique would be broken, but where is that specified in the docs? And if delete is to be deprecated (according to the docs), what is the correct way to do that (despite fact that Unique relies on delete). On Sat, Mar 7, 2015 at 4:02 PM, weaselcat via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > On Saturday, 7 March 2015 at 23:48:39 UTC, Timothee Cour wrote: > >> I'm a little confused about the following: >> clear,delete,destroy. >> My understanding is that clear is deprecated and delete is planned to be >> deprecated, so we should only ever use destroy (which deterministic calls >> the destructor but doesn't release memory). >> >> Unique uses delete however in the destructor. Is that still guaranteeing >> deterministic destruction when the uniqued element is either a class or >> struct? (ie if the destructor has a file handle resource, will it be >> deterministically freed?) >> > > structs are allocated on the stack(unless instantiated with new), and call > their destructor when you leave their scope. Unique still guarantees > deterministic destruction because it's wrapped around a struct, it's a > fairly common 'D idiom' I'd say(i.e, look at how File is implemented - D's > runtime and standard library are surprisingly well documented and easy to > read.) > > I'm not sure why Unique uses delete, might just be bitrot. >
is struct delete deterministic? (cf used in Unique)
I'm a little confused about the following: clear,delete,destroy. My understanding is that clear is deprecated and delete is planned to be deprecated, so we should only ever use destroy (which deterministic calls the destructor but doesn't release memory). Unique uses delete however in the destructor. Is that still guaranteeing deterministic destruction when the uniqued element is either a class or struct? (ie if the destructor has a file handle resource, will it be deterministically freed?)
Re: mixin template scope inconsistency?
posted as bugzilla/14243. Am I misunderstanding something here? On Tue, Mar 3, 2015 at 10:20 PM, Timothee Cour wrote: > Template mixin scope seems to have a weird behavior: > I don't understand 'WEIRD(1)' and 'WEIRD(2)' below. > > import std.stdio; > struct A{ > int b; > this(int b){ > this.b=b; > writeln("A.begin"); > } > ~this(){ > writeln("A.end"); > } > } > > mixin template Entry(){ > auto a=A(12); > } > > void test1(){ > writeln("test.begin"); > mixin Entry; > writeln(a.b);//WEIRD! destructor has been called but a.b is still alive > writeln("test.end"); > } > > void test2(){ > writeln("test.begin"); > auto a=A(0); > writeln("test.end"); > } > > void test3(){ > writeln("test.begin"); > mixin("auto a=A(0);"); > writeln("test.end"); > } > > void main(){ > test1; > writeln; > test2; > writeln; > test3; > } > > output: > > test.begin > A.begin > A.end //WEIRD(1): why is destructor called before test.end? > 12 //WEIRD(2): destructor has been called but a.b is still alive > test.end > > test.begin > A.begin > test.end > A.end > > test.begin > A.begin > test.end > A.end > >
mixin template scope inconsistency?
Template mixin scope seems to have a weird behavior: I don't understand 'WEIRD(1)' and 'WEIRD(2)' below. import std.stdio; struct A{ int b; this(int b){ this.b=b; writeln("A.begin"); } ~this(){ writeln("A.end"); } } mixin template Entry(){ auto a=A(12); } void test1(){ writeln("test.begin"); mixin Entry; writeln(a.b);//WEIRD! destructor has been called but a.b is still alive writeln("test.end"); } void test2(){ writeln("test.begin"); auto a=A(0); writeln("test.end"); } void test3(){ writeln("test.begin"); mixin("auto a=A(0);"); writeln("test.end"); } void main(){ test1; writeln; test2; writeln; test3; } output: test.begin A.begin A.end //WEIRD(1): why is destructor called before test.end? 12 //WEIRD(2): destructor has been called but a.b is still alive test.end test.begin A.begin test.end A.end test.begin A.begin test.end A.end
shallowCopyFrom: how to shallow copy objects / swap contents ?
Is there a standard way to shallow copy objects? eg: class A{ int* a; string b; } unittest{ auto a=new A; a.a=new int(1); a.b="asdf"; auto b=new A; b.shallowCopyFrom(a); assert(b.a==a.a); assert(b.b==a.b); } How about: option A1: void shallowCopyFrom(T)(T a, T b) if(is(T==class)){ size_t size = b.classinfo.init.length; (cast(void*) a)[8 .. size] = (cast(void*) b) [8 .. size]; } Is this guaranteed correct? option A2: auto shallowCopyFrom(T)(T a, T b) if(is(T==class)){ foreach (name; __traits(allMembers, T)) { enum temp="a."~name~"="~"b."~name~";"; static if(__traits(compiles, mixin("{"~temp~"}"))) { mixin(temp); } } } option A2 has issues with property, though. option A1 should also be adaptable to swapping contents.
parse string as char
Is there a simple way to parse a string as a char? eg: unittest{ assert(parseChar(`a`)=='a'); assert(parseChar(`\n`)=='\n'); //NOTE: I'm looking at `\n` not "\n" // should also work with other forms of characters, see http://dlang.org/lex.html } Note, std.conv.to doesn't work (`\n`.to!char does not work)
Re: eraseInPlace (eg using memmove)?
Here's what I'd like in phobos: void eraseInPlace(T)(ref T a, size_t index, size_t n=1) if(isArray!T){ enum s=typeof(a[0]).sizeof; auto ptr=a.ptr+index; import core.stdc.string:memmove; memmove(ptr,ptr+n,(a.length-(index+n))*s); a.length-=n; } unittest{ auto a=[0,1,2,3,4,5,6]; a.eraseInPlace(1,2); import std.conv:text; assert(a==[0,3,4,5,6], text(a)); } (obviously it assumes no aliasing) On Tue, Dec 16, 2014 at 6:59 PM, Timothee Cour wrote: > > Is there a phobos way to do eraseInPlace (eg with optimization using > memmove where appropriate) ? (akin to insertInPlace) >
eraseInPlace (eg using memmove)?
Is there a phobos way to do eraseInPlace (eg with optimization using memmove where appropriate) ? (akin to insertInPlace)
Re: how to redirect stderr to stdout io in spawnProcess (eg stderr to stdout)?
ping? On Tue, Sep 9, 2014 at 6:48 PM, Timothee Cour wrote: > How to redirect io in spawnProcess (eg stderr to stdout)? > > is it safe to use it with a same File object for stderr and stdout as > follows? > Couldn't find this in the docs. > > auto logFile =File(...); > auto pid = spawnShell(command, > std.stdio.stdin, > logFile, > logFile); > >
how to redirect stderr to stdout io in spawnProcess (eg stderr to stdout)?
How to redirect io in spawnProcess (eg stderr to stdout)? is it safe to use it with a same File object for stderr and stdout as follows? Couldn't find this in the docs. auto logFile =File(...); auto pid = spawnShell(command, std.stdio.stdin, logFile, logFile);
spawnShell: how to specify buffering mode (unbuffered, line-buffered, block-buffered)?
Is there a way to specify buffering mode (unbuffered,line-buffered,block-buffered) in spawnShell + friends? This is very useful to have in many applications, eg for logging where one wants to view in progress log results without waiting for entire process to complete or for a 40960-sized block to be written (as is currently the case it seems)
extern(C) function declaration inside a function without altering mangling
Is there way to declare a extern(C) function inside a function without altering the mangled name? Should I write a mixin for that based on pragma(mangleof) (used as extern_C_global_scope in example below) ? Or did someone already implement that? extern(C) void foo1(); void fun(){ extern(C) void foo2(); mixin(extern_C_global_scope("void foo3()")); foo1(); //OK foo2(); //will result in link error due to different mangling of foo2. foo3(); //OK }
Re: RAII limitations in D?
On Thu, Aug 21, 2014 at 7:26 PM, Dicebot via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > http://dlang.org/phobos/std_typecons.html#.RefCounted That doesn't work with classes though; is there any way to get a ref counted class? (and btw RefCounted should definitely appear in http://dlang.org/cpptod.html#raii)
RAII limitations in D?
What would be a good answer to this article? http://swiftcoder.wordpress.com/2009/02/18/raii-why-is-it-unique-to-c/ Especially the part mentioning D:{ D’s scope keyword, Python’s with statement and C#’s using declaration all provide limited RAII, by allowing resources to have a scoped lifetime, but none of them readily or cleanly support the clever tricks allowed by C++’s combination of smart pointers and RAII, such as returning handles from functions, multiple handles in the same scope, or handles held by multiple clients. } This morning I was pointing to some deprecated usage of scope mentioned in docs (EMAIL:scope classes mentioned in tutorials, but deprecated). The pull request (https://github.com/D-Programming-Language/dlang.org/pull/637/files) mentions using struct or classes allocated on the stack via typecons.scoped. However what about the RAII usage mentioned in the above article that allows C++ to return handles for eg (impossible via scope), that get deterministically destroyed?
Deprecation: Read-modify-write operations are not allowed for shared variables
dmd 2.066(rc) generates warning: 'Deprecation: Read-modify-write operations are not allowed for shared variables. Use core.atomic.atomicOp!"-="(a, 1) instead.' for following code: synchronized { ++a; } Is that correct given that it's inside synchronized?
Re: alias to fully qualified enum in scope where enum is expected
On Wed, Aug 6, 2014 at 12:04 PM, via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > On Wednesday, 6 August 2014 at 16:48:57 UTC, Timothee Cour via > Digitalmars-d-learn wrote: > >> Thanks, I know with statement could be used but I was hoping for a >> solution >> not involving adding syntax to call site. >> > > If you control the declaration of the enum, you could write: > > alias a1 = A.a1; > alias a2 = A.a2; > > A bit tedious, but it works, and could be automated if need be. > yes, but that pollutes the scope, what I wanted was to only expose the aliases in places where A is expected, see motivational in previous message: void fun(with(A){A a}, int b){...} //conceptually like this void test(){ int a1=1; fun(A.a1, a1); fun(a1, a1);// first a1 refers to A.a1, second one to local variable int a1 } ok I guess this isn't possible using current semantics.
'with(Foo):' not allowed, why?
Is there a reason why 'with(Foo):' is not allowed, and we have to use with(Foo){...} ? It would be more in line with how other scope definitions work (extern(C) etc)
Re: alias to fully qualified enum in scope where enum is expected
Thanks, I know with statement could be used but I was hoping for a solution not involving adding syntax to call site. void fun(with(A){A a}, int b){...} //conceptually like this void test(){ int a1=1; fun(A.a1, a1); // would work fun(a1, a1);// would work } On Wed, Aug 6, 2014 at 8:22 AM, Meta via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > On Wednesday, 6 August 2014 at 07:23:32 UTC, Rikki Cattermole wrote: > >> The magic of with statements! >> >> enum A { >> a1, >> a2 >> } >> >> void func(A a){} >> void main(){ >> func(A.a1); >> with(A) { >> func(a1); >> } >> } >> > > And if you want to be *really* concise: > > with (A) fun(a1); >
alias to fully qualified enum in scope where enum is expected
Is there a simple way to to do this? enum A{ a1, a2 } void fun(A a){...} void test(){ fun(A.a1); //works fun(a1); //I'd like a1 to work, but just where an A is expected to avoid polluting namespace. }
Re: myrange.at(i) for myrange.dropExactly(i).front
On Sun, Jul 27, 2014 at 9:20 PM, H. S. Teoh via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > On Sun, Jul 27, 2014 at 07:42:17PM -0700, Timothee Cour via > Digitalmars-d-learn wrote: > > Just for clarification, I wanted 'myrange.at(i)' to be the same as > > `myrange.dropExactly(i).front` > > (so I don't assume it's a random access range). > > > > >> myrange.dropExactly(i).front makes it much more obvious what you're > > doing and that it's inefficient. It might be necessary in some cases, > > but we don't want to give the impression that it's cheap, which at() > > would do. > > > > I think it's already clear that it's potentially O(n) [n=i] cost as > > we're not using myrange[i]. But fine, call it atWalk/walkAt/whatever. > > Point is it's a common enough operation. > [...] > > You could just define your own function for it, right? > > // or call it whatever you want > auto getNth(R)(R range, size_t index) > if (isInputRange!R) > { > return range.dropExactly(index).front; > } > > > T > > -- > Making non-nullable pointers is just plugging one hole in a cheese grater. > -- Walter Bright > Obviously I did that, but I thought it belonged in phobos. Anyway, closing this.
Re: myrange.at(i) for myrange.dropExactly(i).front
Just for clarification, I wanted 'myrange.at(i)' to be the same as `myrange.dropExactly(i).front` (so I don't assume it's a random access range). >> myrange.dropExactly(i).front makes it much more obvious what you're doing and that it's inefficient. It might be necessary in some cases, but we don't want to give the impression that it's cheap, which at() would do. I think it's already clear that it's potentially O(n) [n=i] cost as we're not using myrange[i]. But fine, call it atWalk/walkAt/whatever. Point is it's a common enough operation. On Sat, Jul 26, 2014 at 11:15 AM, monarch_dodra via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > On Saturday, 26 July 2014 at 00:28:32 UTC, Ary Borenszweig wrote: > >> No, the OP said the meaning was `myrange.dropExactly(i).front`, which is >> not a random access. >> >> Sometimes you *do* want the n-th element of a range even if the range is >> not a random access. >> > > What he did also say is he wanted the equivalent of C++'s "at", which is > the equivalent of "checked random-access" (or "checked dictionary access"). > > So the actual requirements aren't very clear. In terms of "C++ at" > equivalent, I don't think we have anything equivalent to offer. That said, > I've never seen anyone use "at" in C++ ever. I'd assume it's more of a > java/C# thing to do checked accesses? > >
myrange.at(i) for myrange.dropExactly(i).front
Is there a function for doing this? myrange.at(i) (with meaning of myrange.dropExactly(i).front) it's a common enough operation (analog to myrange[i]; the naming is from C++'s std::vector::at)
__traits(position,symbol) to get the file:line:column:index of a symbol (module,unittest etc)
Wouldn't that be nice? it's all known at CT so why not expose it among other things it'd allow proper association of modules to files in stacktraces (sometimes this is impossible / ambiguous), custom user defined error messages involving lambdas, printing unittest lines etc.
escape string into a C style string litteral (pasteable in C code)
Is there an existing way to do it or do I have to roll my own? unittest{ assert(escapeC(`a"bc\ndef`~"\n") == `"a\"bc\\ndef\n"`); } Likewise with escapeD (pastable in D code), which would return something like: `r"..."` for more readability
findBack: find a needle in a haystack from the back
Is there a more idiomatic/elegant way to achieve the following, while remaining as efficient as possible? Same question in the simpler case n==0? using retro seems inefficient because of all the decodings // returns the largest suffix of a that contains no more than n times c string findBack(string a, char c, size_t n=0){ auto b=cast(immutable(ubyte)[])a; auto val=cast(ubyte)c; size_t counter=0; for(ptrdiff_t i=cast(ptrdiff_t)b.length - 1; i>=0; i--){ if(b[i]==c){ if(counter>=n) return cast(string)a[i+1..$]; counter++; } } return a; } //unittest{ void test3(){ auto c='\n'; string a="abc1\nabc2\nabc3"; assert(a.findBack(c,0)=="abc3"); assert(a.findBack(c,1)=="abc2\nabc3"); assert(a.findBack(c,2)=="abc1\nabc2\nabc3"); assert(a.findBack(c,3)=="abc1\nabc2\nabc3"); }
Re: alias with lambda syntax: alias fun2=a=>fun(a);
ok I remembered we can use std.typetuple.Alias for that. On Wed, Jun 4, 2014 at 11:58 PM, Timothee Cour wrote: > Is there a way to do this? > > import std.algorithm; > > auto fun(T)(T a){return a;} > > template fun2(T){auto fun2(T a){return fun(a);}}//OK but heavy syntax and > cannot be nested inside test() > > void main(){ > //alias fun2=fun!int; //OK but needs to specify template params > //none of those work: > //alias fun2=a=>fun(a); > //alias fun2(T)=(T a)=>fun(a); > //alias fun2(T)=(T a){return fun(a);} > auto b=[1].map!fun2; > assert(b.equal([1])); > } > >
alias with lambda syntax: alias fun2=a=>fun(a);
Is there a way to do this? import std.algorithm; auto fun(T)(T a){return a;} template fun2(T){auto fun2(T a){return fun(a);}}//OK but heavy syntax and cannot be nested inside test() void main(){ //alias fun2=fun!int; //OK but needs to specify template params //none of those work: //alias fun2=a=>fun(a); //alias fun2(T)=(T a)=>fun(a); //alias fun2(T)=(T a){return fun(a);} auto b=[1].map!fun2; assert(b.equal([1])); }
Re: Best way to check for an element in an array?
you can use stuff.canFind(2) but sometimes it'd be more convenient to have the other way around (UFCS chains etc); how about: bool isIn(T,T2...)(T needle, T2 haystack) if(__traits(compiles,T.init==T2[0].init)){ foreach(e;haystack){ if(needle==e) return true; } return false; } unittest{ assert(1.isIn(3,1,2) && !4.isIn(3,1,2)); } On Mon, Apr 21, 2014 at 8:25 PM, Taylor Hillegeist via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > So I find myself Doing this kind of thing very frequently. I have a Array > of Somethings and i want to see if "something specific" is inside the > array. I wrote a template for it. but is this the best way to do this kind > of thing. I feel like it doesn't help with readability. Is there a better > way? Maybe i missed something in the std library. > > import std.stdio; > > template FNDR(T){ > bool isIn(T Element, T[] Array){ > bool rtn=false; > foreach(T ArrayElement; Array){ > if(Element==ArrayElement){ > rtn=true; > } > } > return rtn; > } > } > > void main(string[] args) > { > int[3] stuff=[0,1,2]; > if (FNDR!int.isIn(2,stuff)) > { > writeln("Hello World!"); > } > } > > > Is there a way maybe to make it look like this? > > import std.stdio; > > template FNDR(T){ > bool contains(T[] Array,T Element){ > bool rtn=false; > foreach(T ArrayElement; Array){ > if(Element==ArrayElement){ > rtn=true; > } > } > return rtn; > } > } > > void main(string[] args) > { > int[3] stuff=[0,1,2]; > if (stuff.contains(2)) // Much clean! stuff.FNDR!int.contains(2) > doesn't work > { > writeln("Hello World!"); > } > } > > I'm interested in what you guys think? what is the cleanest way to do this? >
Re: string -> string literal
does that work? string escapeD(string a){ import std.array:replace; return `r"`~a.replace(`"`,`" "\"" r"`)~`"`; } On Sun, Apr 20, 2014 at 11:14 AM, monarch_dodra via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > On Sunday, 20 April 2014 at 17:55:25 UTC, Ellery Newcomer wrote: > >> is there a function in phobos anywhere that takes a string and escapes it >> into a string literal suitable for string mixins? something like >> >> assert (f("abc\ndef") == "\"abc\\ndef\""); >> > > It's a bit hackish, but it avoids deploying code and reinventing anything. > You can use format "string-range" formating to print the string escaped. > Catch that, and then do it again: > > string s = "abc\ndef"; > writefln("[%s]\n", s); //raw > > s = format("%(%s%)", [s]); > writefln("[%s]\n", s); //escaped > > s = format("%(%s%)", [s]); > writefln("[%s]\n", s); //escapes are escaped > > As you can see from the output, after two iterations: > > [abc > def] > > ["abc\ndef"] > > ["\"abc\\ndef\""] > > I seem to recall that printing strings "escaped" has been requested > before, but, AFAIK, this is the best we are currently providing. > > Unless you call std.format's "formatElement" directly. However, this is an > internal and undocumented function, and the fact it isn't private is > probably an oversight. >