Class info on interfaces
I noticed the calling classinfo on an interface returns the class info of the static type and not the dynamic type. Is that intentional? Perhaps because of COM and C++ interfaces? module main; import std.stdio; interface Foo {} class Bar : Foo {} void main() { Foo f = new Bar; writeln(f.classinfo); } The above program will print the static type main.Foo instead of the dynamic type main.Bar. -- /Jacob Carlborg
multiline string literal with CRLF
Is there any way to input such a literal? Both `...` and qEOS...EOS do not allow escape sequences. I'm on Linux, but I need precisely CRLF, not just \n. -- Marek Janukowicz
Re: Should this compile?
On Tuesday, 25 August 2015 at 18:29:08 UTC, Vladimir Panteleev wrote: I think this is a bug, but is easily worked around with: auto test(string a) { return .test(a, b); } Thanks, this worked. Filled it: https://issues.dlang.org/show_bug.cgi?id=14965
Re: Should this compile?
On 08/25/2015 08:29 PM, Vladimir Panteleev wrote: I think this is a bug, but is easily worked around with: auto test(string a) { return .test(a, b); } I suspect that the reason the error occurs, is that the auto return type automatically rewrites the function declaration into an eponymous template declaration. ... No true. In fact, doing so manually works around the problem. :o) This compiles and runs: import std.stdio; import std.range : chain; auto test()(string a) { return test(a,b); } auto test(string a,string b) { return chain(a,b); } void main() { writeln(test(a)); }
Re: Class info on interfaces
On 08/26/2015 11:59 AM, Adam D. Ruppe wrote: On Wednesday, 26 August 2015 at 18:53:19 UTC, Jacob Carlborg wrote: Is that intentional? Perhaps because of COM and C++ interfaces? Yes, exactly. COM and C++ things won't necessarily have a D TypeInfo available and since interfaces can be them, it can't be sure. What I do there is to just cast the interface to Object. Then you should check for null to cover those cases, then you can typeid or classinfo it. To complete, the documentation says .classinfo applied to an interface gives the information for the interface, not the class it might be an instance of. http://dlang.org/property.html#classinfo Ali
Re: Should this compile?
On 08/26/2015 09:55 PM, Timon Gehr wrote: On 08/25/2015 08:29 PM, Vladimir Panteleev wrote: I think this is a bug, but is easily worked around with: auto test(string a) { return .test(a, b); } I suspect that the reason the error occurs, is that the auto return type automatically rewrites the function declaration into an eponymous template declaration. ... No true. In fact, doing so manually works around the problem. :o) This compiles and runs: import std.stdio; import std.range : chain; auto test()(string a) { return test(a,b); } auto test(string a,string b) { return chain(a,b); } void main() { writeln(test(a)); } Another workaround is to order the declarations in the opposite way: import std.stdio; import std.range : chain; auto test(string a,string b) { return chain(a,b); } auto test(string a) { return test(a,b); } void main() { writeln(test(a)); }
Re: multiline string literal with CRLF
anonymous wrote: Is there any way to input such a literal? Both `...` and qEOS...EOS do not allow escape sequences. I'm on Linux, but I need precisely CRLF, not just \n. I'm probably missing the point, but: Hello\r\nworld Or if you want to include the \n verbatim: Hello\r world Thanks, this works - I don't know how I did it the first time, because I definitely tried that and failed. The other solution by Adam also works - thanks. -- Marek Janukowicz
Re: Class info on interfaces
On Wednesday, 26 August 2015 at 18:53:19 UTC, Jacob Carlborg wrote: Is that intentional? Perhaps because of COM and C++ interfaces? Yes, exactly. COM and C++ things won't necessarily have a D TypeInfo available and since interfaces can be them, it can't be sure. What I do there is to just cast the interface to Object. Then you should check for null to cover those cases, then you can typeid or classinfo it.
Re: multiline string literal with CRLF
On Wednesday, 26 August 2015 at 18:28:02 UTC, Marek Janukowicz wrote: Is there any way to input such a literal? Both `...` and qEOS...EOS do not allow escape sequences. I'm on Linux, but I need precisely CRLF, not just \n. One way you could do it is to stick a .replace(\n, \r\n) to the end of the literal. If it is in a compile time context, it will CTFE its way to a new literal for you.
Re: multiline string literal with CRLF
On Wednesday 26 August 2015 20:28, Marek Janukowicz wrote: Is there any way to input such a literal? Both `...` and qEOS...EOS do not allow escape sequences. I'm on Linux, but I need precisely CRLF, not just \n. I'm probably missing the point, but: Hello\r\nworld Or if you want to include the \n verbatim: Hello\r world
MmFile : Is this std.mmFile BUG?
Hi, all. I have a question. When 'testdic' file does' t exist, something wrong. --- import std.mmFile; int main() { auto x = new MmFile(testdic,MmFile.Mode.readWrite,0,null); return 0; } --- OSX 10.10.3 , DMD64 D Compiler v2.069-devel-d0327d9 After testdic file (size=0) was made, Segmentation Fault: 11 . I don't know whether this code is typical use. Is this Phobos BUG? or BY DESIGN?
Re: __traits(allMembers) and aliases
On 08/26/15 14:42, Mike Parker via Digitalmars-d-learn wrote: This doesn't help me distinguish aliased function names. [...] I don't want to put any restrictions on what the user can have in the module/class/struct that contains the function pointer. It's just that aliased function names pass both tests as they are synonyms for the functions they alias. If it's just about functions then you can check identity (the address obtained via the alias will be the same). That will also work for other non-tls objects. It won't work for tls objects because the compiler will (incorrectly) reject the equality check at CT. Because of D's implicit TLS in module and static scopes, a lot of objects will unintentionally be made thread local, so this solution won't be practical until the compiler limitation goes away, yes. artur
Re: MmFile : Is this std.mmFile BUG?
On Wednesday, 26 August 2015 at 15:49:23 UTC, Junichi Nakata wrote: Hi, all. I have a question. When 'testdic' file does' t exist, something wrong. --- import std.mmFile; int main() { auto x = new MmFile(testdic,MmFile.Mode.readWrite,0,null); return 0; } --- OSX 10.10.3 , DMD64 D Compiler v2.069-devel-d0327d9 After testdic file (size=0) was made, Segmentation Fault: 11 . I don't know whether this code is typical use. Is this Phobos BUG? or BY DESIGN? Note that mmap-ing a zero-length range is invalid on Linux. Dunno about OSX; it shouldn't segfault though.
Re: RAII and Deterministic Destruction
Thanks for the thorough response. I'm aware of some of what you explained. Maybe I should have asked differently. Rather than asking what RAII facilities do exist, I guess I was looking for the answer, Here's what you typically do in C++ RAII that you can't do in D. I could probably find out things by experimenting too (and not be too lazy). I just didn't want to rely on my assumptions only. For example, say object A is a member of object B which is in turn a member of object C. If C is deleted or goes out of scope, does the destructor of A get called? If all three are classes, obviously not. But if all three are structs? What if they are classes but are all managed by Unique? If I use Unique for all of my heap-allocated classes (as I would with std::unique_ptr in C++) am I assured of destructors being called when the owning classes get destructed? I'm wondering about these various nesting/owning combinations. Jim
Re: RAII and Deterministic Destruction
Thanks. I had not looked at some of those yet. Jim
Re: RAII and Deterministic Destruction
Thanks for all the info. It's a good comparison of structs and classes to keep handy. Actually, I'm fine with the GC. I don't mean to avoid it. I just would like some way to also have non-memory resources automatically released in a timely, predictable way. One common thing to do in C++ is to manage the lifetime of an object with std::unique_ptr but then use its .get() function to get a native pointer to use temporarily. You just have to ensure that the native pointer doesn't outlive the unique_ptr, which isn't that difficult. True, if the unique_ptr gets destructed the native pointer is invalid and that could be risky, but you limit its use. Unique in D doesn't seem to have anything like a get() function but I wonder if it could. That is, it would get another native reference to the Unique resource that is managed by the garbage collector. So if the Unique went out of scope and got destructed, the reference would at least refer to valid memory although not a valid object because its destructor had already been called. Not perfectly safe, but no worse than the C++ case. Just a thought. Jim
Re: Adding UDA at compile time
On Wednesday, 26 August 2015 at 14:29:30 UTC, Andrea Fontana wrote: __traits(setAttributes, ...) It would be useful, for example, if I have a list of functions to mark. Let's say enum toExport = [oldFunction, thisToo]; foreach(d; toExport) __traits(setAttributes, ...); Lots of compile-time information is fixed after the symbol is defined, making it effectively immutable. There's not, for example, a `__traits(setType, var)`. If you want to apply a UDA to many functions at once, you can use the block syntax: @(hello) { void foo1() {} void foo2() {} } // or alternatively @(hello): void foo3() {} void foo4() {} Also if you're talking about the `export` keyword, then that's not a UDA.
Re: MmFile : Is this std.mmFile BUG?
On Wednesday, 26 August 2015 at 17:30:29 UTC, Alex Parrill wrote: On Wednesday, 26 August 2015 at 15:49:23 UTC, Junichi Nakata wrote: Hi, all. I have a question. When 'testdic' file does' t exist, something wrong. --- import std.mmFile; int main() { auto x = new MmFile(testdic,MmFile.Mode.readWrite,0,null); return 0; } --- OSX 10.10.3 , DMD64 D Compiler v2.069-devel-d0327d9 After testdic file (size=0) was made, Segmentation Fault: 11 . I don't know whether this code is typical use. Is this Phobos BUG? or BY DESIGN? Note that mmap-ing a zero-length range is invalid on Linux. Dunno about OSX; it shouldn't segfault though. https://issues.dlang.org/show_bug.cgi?id=14968
Re: Decrease number of front evaluations
On Wed, 26 Aug 2015 08:27:05 +, FreeSlave wrote: Are there ways to fix this? Should I consider writing my own range type probably? Check http://dlang.org/phobos/std_algorithm_iteration.html#.cache
Re: Decrease number of front evaluations
On Wednesday, 26 August 2015 at 08:30:04 UTC, Yazan D wrote: On Wed, 26 Aug 2015 08:27:05 +, FreeSlave wrote: Are there ways to fix this? Should I consider writing my own range type probably? Check http://dlang.org/phobos/std_algorithm_iteration.html#.cache I tried it. It can help with map (still calls 2 times though) but the number of filter's predicate calls stay the same.
Adding UDA at compile time
I wonder if there's a way to add UDA to functions at compile-time (so I can read later from other parts of application). Andrea
Re: Decrease number of front evaluations
On 08/26/2015 01:27 AM, FreeSlave wrote: I would want to avoid redundant front evaluations. Another option is std.functional.memoize: import std.stdio; import std.functional; import std.algorithm; import std.array; void main() { auto r = [ 1, 2, 1 ] .map!(memoize!(delegate(int a) { writefln(map for %s, a); return a; })) .filter!(memoize!(delegate(int a) { writefln(filter for %s, a); return a; })); r.each; } Although there are two 1s, the second one is not evaluated because the result of the first one is used: map for 1 filter for 1 map for 2 filter for 2 Ali
Decrease number of front evaluations
Example: import std.stdio; import std.algorithm; import std.path; import std.file; import std.exception; import std.getopt; import std.array; import std.range; auto algo(string fileName, string[] dirs, string[] extensions) { return dirs.filter!(delegate(dir) { bool ok; collectException(dir.isDir, ok); return ok; }).map!(dir = extensions .map!(delegate(ext) { string path = buildPath(dir, fileName ~ ext); writefln(Map: %s, path); return path; }).filter!(delegate(filePath) { bool ok; writefln(Check: %s, filePath); collectException(filePath.isFile, ok); return ok; }) ).joiner; } void main(string[] args) { string fileName; string extensionsStr; getopt(args, fileName, file name to search without extension, fileName, extensions, list of extensions separated by ':', extensionsStr ); string[] dirs = args[1..$]; if (fileName.empty) { stderr.writeln(File name not given); return; } if (dirs.empty) { dirs = [.]; } string[] extensions = extensionsStr.splitter(':').array; if (extensions.empty) { extensions = [.d]; } foreach(item; algo(fileName, dirs, extensions)) { writefln(Found: %s, item); } } When I run this it like this (assuming main.d exists): main --fileName=main It gives me: Map: .\main.d Check: .\main.d Map: .\main.d Check: .\main.d Map: .\main.d Check: .\main.d Map: .\main.d Found: .\main.d In this simple example it calls map 4 times and filter 3 times. The map transformer and filter predicate can be expensive, so I would want to avoid redundant front evaluations. The real code is more complicated and can be found here https://github.com/MyLittleRobo/icontheme/blob/master/source/icontheme.d#L427 It can call filter's predicate with the same argument up to 8 times, which is not nice. Are there ways to fix this? Should I consider writing my own range type probably?
Casting pointers
This would be undefined behavior in c++ due to aliasing rules on pointers. It appears to work reliably in D when I try it, but that's obviously no guarantee that it's correct or will continue to do so. Is this correct code in D? And if not, what should I do instead to cleanly and efficiently extract structured data from a sequence of bytes? import std.stdio; struct data { int a; int b; } void main() { byte[] x = [1, 2, 3, 4, 5, 6, 7, 8]; data* ptr = cast(data*)(x); printf(%x %x\n, ptr.a, ptr.b); }
Re: __traits(allMembers) and aliases
On Tuesday, 25 August 2015 at 12:06:08 UTC, Mike Parker wrote: Is there a way to determine whether a given symbol is an alias? Consider this: ``` module funcs; alias FuncPtr = void function(); @ChooseMe FuncPtr funcPtr; alias anotherName = funcPtr; ``` Handing this module off to __traits(allMembers), then checking for the UDA on each member, I can filter out FuncPtr just fine. Unfortunately, anotherName passes the test, but I don't want it to. Is there anyway I can distinguish the anotherName alias from funcPtr without tagging it with a UDA? I can't find any sort of isAlias trait anywhere. I've been doing work on this recently. As far as I can tell, there is no way to do this. The problem is that an alias behaves exactly like the thing being aliased since it's just a name replacement, so there are no giveaways like being unable to take its address like enums. Aliases are more or less invisible. Hence, having an isAlias trait would be a really good idea.
Re: __traits(allMembers) and aliases
On Tuesday, 25 August 2015 at 16:08:48 UTC, Rikki Cattermole wrote: \ While my memory especially at 4am is rusty here: enum isVarDecl = __traits(compiles, {mixin(GOT ~ got;);}); Where GOT is assumed to be the string that you got from __traits(allMembers. It'll be true that it is a variable declaration. False for anything else e.g. a type. This doesn't help me distinguish aliased function names. The ideal thing to do is simply to check isFunctionPtr and hasUDA. I don't want to put any restrictions on what the user can have in the module/class/struct that contains the function pointer. It's just that aliased function names pass both tests as they are synonyms for the functions they alias.
Re: __traits(allMembers) and aliases
On Wednesday, 26 August 2015 at 11:20:40 UTC, Meta wrote: I've been doing work on this recently. As far as I can tell, there is no way to do this. The problem is that an alias behaves exactly like the thing being aliased since it's just a name replacement, so there are no giveaways like being unable to take its address like enums. Aliases are more or less invisible. Hence, having an isAlias trait would be a really good idea. +1 That's the first thing I was looking for. https://issues.dlang.org/show_bug.cgi?id=14964
Re: Adding UDA at compile time
On Wednesday, 26 August 2015 at 14:01:00 UTC, Alex Parrill wrote: On Wednesday, 26 August 2015 at 08:19:04 UTC, Andrea Fontana wrote: I wonder if there's a way to add UDA to functions at compile-time (so I can read later from other parts of application). Andrea What do you mean? UDAs are already specified at compile time. @(hello) void foo() { } static assert(__traits(getAttributes, foo)[0] == hello); __traits(setAttributes, ...) It would be useful, for example, if I have a list of functions to mark. Let's say enum toExport = [oldFunction, thisToo]; foreach(d; toExport) __traits(setAttributes, ...);
Re: Adding UDA at compile time
On Wednesday, 26 August 2015 at 08:19:04 UTC, Andrea Fontana wrote: I wonder if there's a way to add UDA to functions at compile-time (so I can read later from other parts of application). Andrea What do you mean? UDAs are already specified at compile time. @(hello) void foo() { } static assert(__traits(getAttributes, foo)[0] == hello);
Re: RAII and Deterministic Destruction
A serious bug affecting RAII is https://issues.dlang.org/show_bug.cgi?id=14903, but apparently its importance hasn't been properly acknowledged yet. Improving the performance of binaries produced by dmd's backend is obviously way more important than fixing serious bugs or commenting on related PRs.
Re: Casting pointers
On Wednesday 26 August 2015 14:14, John Burton wrote: This would be undefined behavior in c++ due to aliasing rules on pointers. It appears to work reliably in D when I try it, but that's obviously no guarantee that it's correct or will continue to do so. Is this correct code in D? And if not, what should I do instead to cleanly and efficiently extract structured data from a sequence of bytes? import std.stdio; struct data { int a; int b; } void main() { byte[] x = [1, 2, 3, 4, 5, 6, 7, 8]; data* ptr = cast(data*)(x); printf(%x %x\n, ptr.a, ptr.b); } There's an open issue about it: https://issues.dlang.org/show_bug.cgi?id=10750 I don't know where we stand exactly, but by the looks of it, strict aliasing has never been added to the spec. So compilers should not assume it. As David Nadlinger points out: There is already quite a lot of D code out there that violates the C-style strict aliasing rules. I think that code should be fine for now. If it isn't, we have a problem, because with a silent spec we have no way of knowing what alternatives should work.
Re: Should this compile?
On Wednesday, 26 August 2015 at 20:02:35 UTC, Timon Gehr wrote: Another workaround is to order the declarations in the opposite way: import std.stdio; import std.range : chain; auto test(string a,string b) { return chain(a,b); } auto test(string a) { return test(a,b); } void main() { writeln(test(a)); } It's definitely a bug if the code is dependent on order of declaration.
Re: linking-in libs under linux needed and not under windows
On Thursday, 27 August 2015 at 02:50:58 UTC, BBasile wrote: So the Q: Is this difference normal ? Yes, it is a feature the Windows format supports but the Linux one doesn't. On Linux, you need to list the libraries on the command line again.
Re: linking-in libs under linux needed and not under windows
On Thursday, 27 August 2015 at 03:17:57 UTC, BBasile wrote: On Thursday, 27 August 2015 at 02:50:58 UTC, BBasile wrote: So the Q: Is this difference normal ? the win OMF linux COFF thing maybe ? If I understand your problem description correctly, the culprit is likely the order in which the libraries are passed to the linker. The way the GNU linker works requires any library X that depends on any library Y to be placed before library Y on the command line. So, given your example, if libB uses symbols from libA, then it needs to come before libA on the command line. dmd sourceProject.d -L-lB -L-lA -IpathToSourceA -IpathToSourceB You can also see this when you use the pragma(lib) feature, as dmd passes the libraries to the linker in the order in which it found the pragmas.
Re: linking-in libs under linux needed and not under windows
On Thursday, 27 August 2015 at 02:50:58 UTC, BBasile wrote: So the Q: Is this difference normal ? the win OMF linux COFF thing maybe ?
Re: MmFile : Is this std.mmFile BUG?
On Wednesday, 26 August 2015 at 22:07:01 UTC, rsw0x wrote: On Wednesday, 26 August 2015 at 17:30:29 UTC, Alex Parrill wrote: On Wednesday, 26 August 2015 at 15:49:23 UTC, Junichi Nakata wrote: Hi, all. I have a question. When 'testdic' file does' t exist, something wrong. --- import std.mmFile; int main() { auto x = new MmFile(testdic,MmFile.Mode.readWrite,0,null); return 0; } --- OSX 10.10.3 , DMD64 D Compiler v2.069-devel-d0327d9 After testdic file (size=0) was made, Segmentation Fault: 11 . I don't know whether this code is typical use. Is this Phobos BUG? or BY DESIGN? Note that mmap-ing a zero-length range is invalid on Linux. Dunno about OSX; it shouldn't segfault though. From OS X 10.10.3 manage on mmap: ERRORS ... [EINVAL] The len argument was negative. append to https://issues.dlang.org/show_bug.cgi?id=14968 thanks.
linking-in libs under linux needed and not under windows
let's say i have 'libA', 'libB' and 'Project' - libB uses libA - Project uses libB under Windows (32 bit, OMF objects, Digital Mars linker, so the standard setup): - * libA is compiled with: dmd sourceA.d -lib * libB is compiled with: dmd sourceB.d -lib -IpathToSourceA * Project is compiled with: dmd sourceProject.d libA.lib libB.lib -IpathToSourceA -IpathToSourceB and it just works fine under Linux (64 bit, also the standard setup): --- The same procedure fails with some messages (undefined this and that...) but if i link incrementaly (so i link libA in libB) it works: * libA is compiled with: dmd sourceA.d -lib * libB is compiled with: dmd sourceB.d libA.a -lib -IpathToSourceA * Project is compiled with: dmd sourceProject.d libA.a libB.a -IpathToSourceA -IpathToSourceB So the Q: Is this difference normal ? Why I ask this ? The problem is that I've made a change to Coedit recently that is based on the way it works on Windows: https://github.com/BBasile/Coedit/blob/master/src/ce_nativeproject.pas#L373 That does that: libraries files are only passed when the output binary must contain everything (so an executable). The problem is verified with a lib which uses two Derelict libs that use themselves DerelictUtil...I could just put a compiler switch in the .pas source to have the right behaviour according to the platform but i'd like an explanation...this difference looks weird.