Re: using this instead of typeof(this)
On 26/02/2013 18:41, bearophile wrote: Kenji Hara: auto return is a little different with others. To infer return type, the method body is aggressively analyzed in compilation. So that usage of auto sounds like something to avoid if you want D compiler to compile quickly a lot of code. I suspect it doesn't matter actually. The semantic analysis of the function body is going to have to happen anyway. It all depends on whether the compiler does an extra pass which it throws away the work of - which seems fairly unlikely to me (having written a couple of Java type resolvers I could have done without having to write xD).
Re: scope(exit) stack = double free or corruption (fasttop) ... help?
On 26/02/2013 06:21, Charles Hixson wrote: On 02/24/2013 05:39 PM, H. S. Teoh wrote: On Sun, Feb 24, 2013 at 03:14:01PM -0800, Charles Hixson wrote: Given a struct with: ~this() { close();} voidclose() { if(currentKey !is null)currentKey=null; if(cursor is null)return; tcbdbcurdel(cursor); } and: scope (exit)if (bdb !is null) tcbdbclose(bdb); //scope(exit)cur.close; //- cur is the struct noted above [...] The struct dtor is automatically called upon exiting the scope, so your scope(exit) here is redundant, and is the cause of the double free. T Sorry, but that wasn't the answer...which was trivial, when I saw it. I needed to change the close() routine to: voidclose() { if(currentKey !is null)currentKey=null; if(cursor is null)return; tcbdbcurdel(cursor); cursor = null; } Apparently the library didn't null the cursor after it closed (deleted) it. You're both right. Your struct is presumably declared as a simple local variable, like this: someFunction() { YOUR_STRUCT cur; ... } What we're saying is that cur's destructor is called automatically as soon as execution reaches the }, even if an exception is thrown or a break/continue/return/goto jumps out. So when you write scope (exit) cur.close();, you're queueing the close() to happen under the same circumstances. This doesn't stop the destructor call happening. Your destructor calls close() too, so it gets called twice. You should also know that the library you're using *can't* set 'cursor' to null for you, because you're in control of the memory location where 'cursor' is stored (it's inside your struct), and when you pass it to tcbdbcurdel(), you're only passing a copy of the value. In order for it to set it to null for you, you would have pass a pointer to the value, by writing 'cursor'. (This is not strictly true for D or C++ functions since they can take 'references' which are implicit pointers, but you said it's a C library - and in any case, 'ref' parameters will usually be much more obviously 'ref' parameters than this one, if the API is well designed.) So - setting cursor to null is a good safe fix, as it makes it safe to call close() more than once - but you also don't need the 'scope (exit)', as you can rely on the destructor being called. (But further to that - you can only rely on the destructor being called if it's a struct (and not a pointer to one), or a scope class (a class with the 'scope' attribute). Normal classes will be destroyed eventually by the GC, but not at a well-defined time, and there's (probably?) no guarantee it'll be called before the program exits.) I guess D isn't as simple as it wanted to be! But it is powerful :)
Re: static class
On 18/02/2013 21:25, Michael wrote: Yes, it's comes from C#. So, there is no static for classes at module level. Good to have a msg for it at compile-time. import std.stdio; public final abstract class Test { static this() { writeln(in static ctor); } static : void foo() { writeln(in static method); } } void main() { Test.foo(); } public - adds a little bit of verbosity (ref http://wiki.dlang.org/Access_specifiers_and_visibility). For now is noop. final - adds a no inheritance. abstract - disables non-static ctors. right? Technically 'abstract' doesn't disable the ctors; they would still be called by super() if you had a subclass (if you didn't use 'final'). What 'abstract' does is insist that all instances must be of some subtype, not of the class itself. I'm sure you knew that and it's just a wording thing :) Fun fact: in Java, it's an error to combine 'final' and 'abstract'.
Re: static class
On 17/02/2013 22:25, Jonathan M Davis wrote: On Sunday, February 17, 2013 23:00:19 Michael wrote: That's not the meaning of static in that context. As I understand a static class can't be instantiated. I have no idea how you came to that conclusion. In fairness, it is the natural guess you'd make if you haven't actively used nested instance classes and understood how the outer instance pointer is stored. We use Java at work (same mechanism as D), and hardly anyone actually knows to write 'static' when they create a nested class that they intend to be POD. :) That's not what it means for a class to be static at all. The only place that static has any effect on classes is for nested classes. A static, nested class is like any other class except that it's inside another class, which affects its path. e.g. module b; class C { static class W { } } W is therefore b.C.W, whereas if it were not nested inside of C but next to it within the same module, then it would be b.W. However, non-static nested classes are associated with an instance of the outer class, and therefore only one can exist per class instance. That's not true, is it? You can make as many nested instances as you like. It's just that there must be some outer instance available at the time of construction (which can be a new one each time or the same one every time or anything in between). However, it also has access to that outer class instance through the property outer. e.g. class C { class R { void func() { //Sets the variable in the instance of //C that it's associated with. outer.i = 7; } } int i; } Is it possible to write someInstanceOfR.outer? I've occasionally wanted Java to have that feature, and ended up storing the 'outer' reference manually. Though this probably means I was writing bad code; I can't remember. :D
Re: For DLLs, what does export actually do?
On 11/02/2013 16:06, Regan Heath wrote: On Sun, 10 Feb 2013 12:36:38 -, Ben Davis ent...@cantab.net wrote: DllMain is a weird one - it creates all sorts of linker errors if I try it with extern(C) instead of extern(Windows) (which is different from the other methods, which compile fine with extern(C) and then crash at runtime). extern(C) will change the mangling.. so in this case I guess the linker is expecting DllMain but the mangling is incorrect. I wonder if the compiler detects the presence of DllMain and alters the linker line. DMD has a command line option to output the linker command line, maybe see if it changes with/without a DllMain in the code perhaps. I think that's exactly what's going on. If it was only the mangling, I'd expect one error relating to that function, but instead I get at least 10 errors relating to various functions I've never heard of. I don't think there's any particular need to test further. Also it doesn't matter what name I export it by or whether I export it at all. I'm getting the feeling this is what was implied by The presence of DllMain() is recognized by the compiler. Good to know anyway - I like to keep stuff clean :) Yep, DllMain isn't a requirement, but if is present should be called by the C runtime when the dll is loaded. You can hook into process start/stop and thread attach/detach with dll main. It's good for thread local storage initialisation - for example. Yep, sounds about right - and it sounds like something that gets resolved in a special way when the DLL is linked. Certainly DllMain isn't appearing in my export table, yet I've established (by calling MessageBoxA from inside DllMain - that was brave of me, wasn't it? :P) that it is being called. :)
Re: How to interface to a C struct with volatile variables?
On 16/02/2013 03:54, Charles Hixson wrote: Does D have an equivalent to the C marking of volatile? Currently I'm just going to try removing all variables from the struct, as it's never declared in D or accessed from within D, and I just want to avoid cast(void*)s, but I may need to access something like this sometime in the future. In your case, I think you can declare opaque structs in D: struct S; //Opaque struct S { ... }//Not opaque As for 'volatile', there's some info at http://dlang.org/deprecate.html#volatile about how it used to be available for marking statements as 'do not optimise field accesses'. The corrective action listed there is to use 'synchronized' instead. So probably your best bet is to use 'synchronized' blocks wherever you access the variables that you know are meant to be volatile. Hope that helps :)
Re: How to interface to a C struct with volatile variables?
On 16/02/2013 15:19, Jacob Carlborg wrote: On 2013-02-16 15:13, Ben Davis wrote: As for 'volatile', there's some info at http://dlang.org/deprecate.html#volatile about how it used to be available for marking statements as 'do not optimise field accesses'. The corrective action listed there is to use 'synchronized' instead. So probably your best bet is to use 'synchronized' blocks wherever you access the variables that you know are meant to be volatile. Hope that helps :) If you're interfacing with C you should just remove the volatile statement/keyword. There is no volatile type modifier in D. To declare a C function that uses volatile, just drop the keyword from the declaration. http://dlang.org/interfaceToC.html That's only telling you how to declare a C *function*, not a C struct (or global). While you'll probably get away with it in practice, I think dropping it from a struct is technically unsafe (and may break as a result of future compiler optimisation improvements) unless you back it up with the 'synchronized' strategy. I was going to suggest __gshared, but for struct members it implies static, so it's not what you want. There doesn't seem to be a way to make a struct member 'volatile' for the purposes of interacting with C (which seems to be a gap in the C support).
Re: For DLLs, what does export actually do?
On 10/02/2013 08:17, Benjamin Thaut wrote: Am 10.02.2013 03:03, schrieb Ben Davis: My functions are export extern (Windows) - I think they're global...? For example: export extern(Windows) LRESULT DriverProc(DWORD_PTR dwDriverId, HDRVR hdrvr, UINT msg, LONG lParam1, LONG lParam2) nothrow { ... } Do you have a copy of visual studio around? If so you can use dumpbin /EXPORTS your.dll From a visual studio command shell to see the symbols the dll actually exports. Just compare the version where you manually listed them in the exports section with the version where you don't manually list exports. Thanks, that helped expose what's going on. With the def, I get lines like DriverProc = _DriverProc@20. Without it, I get lines like _DriverProc@20 = _DriverProc@20. So the difference is that the export is done under a slightly mangled name if I only mark it in the code, and I need to use the def file to specify the exact name to export by. I suppose this is only necessary for weird things like driver entry points, and not for normal exported functions. A bit more Googling reveals that the @n is the number of bytes taken by arguments, and is part of the stdcall == extern(Windows) convention. So Windows is making me use stdcall and then making me throw that information away in the export table. But hey - it wouldn't be the worst thing I've encountered with the Windows API. (._.' :P) DllMain is a weird one - it creates all sorts of linker errors if I try it with extern(C) instead of extern(Windows) (which is different from the other methods, which compile fine with extern(C) and then crash at runtime). Also it doesn't matter what name I export it by or whether I export it at all. I'm getting the feeling this is what was implied by The presence of DllMain() is recognized by the compiler. Good to know anyway - I like to keep stuff clean :)
Re: For DLLs, what does export actually do?
On 10/02/2013 12:39, Benjamin Thaut wrote: Am 10.02.2013 13:36, schrieb Ben Davis: With the def, I get lines like DriverProc = _DriverProc@20. Without it, I get lines like _DriverProc@20 = _DriverProc@20. Then you did hit this 3 year old bug: http://d.puremagic.com/issues/show_bug.cgi?id=3956 I don't think I did. That bug applies to cases WITHOUT a .def file, and in that bug, the actual vs expected output is: _DriverProc@mangledinsomeway (correct) modMessage@mangledinsomeway (should be _modMessage@mangledinsomeway) midMessage@mangledinsomeway (should be _midMessage@mangledinsomeway) In my case, when I build without a .def file, I get: _DriverProc@mangledinsomeway _modMessage@mangledinsomeway _midMessage@mangledinsomeway not what I want, but correct as per the spec (I assume). Which would imply the bug was fixed at some point. My example of DriverProc = (without the _) was WITH a .def file, AND is what I want - there is no bug as far as I'm aware. For reference, when Andrej mentioned in earlier bug involving not having a .def, I thought of this one: http://www.digitalmars.com/d/archives/digitalmars/D/Windows_DLLs_and_TLS_177871.html Hope it's clear now? Ben :)
Re: For DLLs, what does export actually do?
On 10/02/2013 14:11, Ben Davis wrote: Which would imply the bug was fixed at some point. ...though of course it would need verifying with the example actually quoted in the bug, since there may be subtle differences. (Hopefully I'm just stating the obvious.)
Re: For DLLs, what does export actually do?
On 09/02/2013 20:44, Andrej Mitrovic wrote: On 2/9/13, Ben Davis ent...@cantab.net wrote: Hi, I'm working on a multimedia driver DLL, i.e. one that Windows loads on behalf of any program that uses the Windows multimedia API. I'm using a .def file with an EXPORTS section, and I've also got all the relevant functions marked as 'export' in the code. Export in code allows you to avoid listing exported functions in the DEF file. However you should likely still use the DEF file even if it lacks a list, as I recall there's a bug related to not using DEF files (I can't find the issue right now). (Oops, silly Thunderbird) I know which issue you mean, because I came across it earlier. It's something about needing EXETYPE NT and SUBSYSTEM WINDOWS or else something bad happens with thread-local storage. I don't think it had anything to do with exports. What you're telling me (about the purpose of export in code) is what I assumed was the intention, but the fact is it's not behaving that way. If I mark the functions as export in the code, but remove the EXPORTS section from the .def file (but keep the rest of the .def file), then the DLL doesn't work, which suggests that the export table did not contain those functions. Perhaps the exports in the code only apply if the .def is entirely missing? Is that the desired behaviour? (I won't be trying that, as I know it would break in other ways then.) Ben :)
Re: For DLLs, what does export actually do?
On 09/02/2013 20:39, Benjamin Thaut wrote: Am 09.02.2013 21:35, schrieb Ben Davis: Hi, I'm working on a multimedia driver DLL, i.e. one that Windows loads on behalf of any program that uses the Windows multimedia API. I'm using a .def file with an EXPORTS section, and I've also got all the relevant functions marked as 'export' in the code. What I'm finding is, if I remove the 'export' attribute but keep the EXPORTS section, it all still works; but if I keep the 'export' attribute and remove the EXPORTS section, then it doesn't work. Just wondering why this is, and whether the 'export' attribute is actually programmed to do anything at the moment :) Thanks, Ben :) Yes it is, but its only working properly for global functions. It works partially for classes and not at all for all remaining cases. The export attribute is currently only usefull if you want to do a C-Style interface for your Dll. My functions are export extern (Windows) - I think they're global...? For example: export extern(Windows) LRESULT DriverProc(DWORD_PTR dwDriverId, HDRVR hdrvr, UINT msg, LONG lParam1, LONG lParam2) nothrow { ... }
Automatic return type covariance for functions that return this?
Hi, Is it possible in D to achieve this effect: class Super { typeof(this) doStuff() { ...; return this; } } class Sub : Super { //doStuff is NOT explicitly overridden here } Sub x = (new Sub()).doStuff(); The last line doesn't compile because doStuff() returns Super. Is there a way to make it return Sub without having to explicitly override the function? Thanks in advance, Ben :)
Re: Automatic return type covariance for functions that return this?
Never mind, I found the answer in the 'templates' page of the spec: class Super { T doStuff(this T)() { ...; return cast(T)this; } } Sub x = (new Sub()).doStuff(); It seems a bit of a shame that I need the cast, but it's a small thing :) On 15/09/2012 22:53, Ben Davis wrote: Hi, Is it possible in D to achieve this effect: class Super { typeof(this) doStuff() { ...; return this; } } class Sub : Super { //doStuff is NOT explicitly overridden here } Sub x = (new Sub()).doStuff(); The last line doesn't compile because doStuff() returns Super. Is there a way to make it return Sub without having to explicitly override the function? Thanks in advance, Ben :)
Re: Const lazy arguments?
If you had a const lazy SomeClass con and a lazy SomeClass mut, you could write mut.x=y but not con.x=y. I think. On 11/01/2012 04:46, bearophile wrote: I ask here first before submitting about this to Bugzilla. If lazy arguments can't be lvalues: void foo(lazy int x) { x = x; } void main() {} == test.d(2): Error: lazy variables cannot be lvalues What's the point of accepting const lazy arguments? void foo(const lazy int x) {} void main() {} Bye, bearophile
Ref local variables?
Hi, Is there a reason 'ref' is disallowed for local variables? I want to write something like: MapTile[] map; // It's a struct ref MapTile tile=map[y*w+x]; tile.id=something; tile.isWall=true; My actual case is more complicated, so inlining the expression everywhere would be messy. I can't use 'with' because I sometimes pass 'tile' to a function (which also takes it as a ref). I don't want to make it a class since the array is quite big and that would be a lot of extra overhead. For now I'm using pointers, but this is forcing me to insert or * operators sometimes, and it also reduces the temptation to use 'ref' in the places where it IS allowed, since it's inconsistent. I hope it's not a stupid question - it's my first one - but I couldn't find an answer anywhere. I like most of what I've seen of D so far, and I'm very glad to be able to leave C and C++ (mostly) behind! Thanks, Ben :)
Re: Ref local variables?
I also meant to say: 80x25? Epic :D On 08/01/2012 20:25, Ben Davis wrote: There are two things going on in your example: 1. Use of 'auto' where I'm currently having to write 'MapTile*' and wanted to write 'ref MapTile'. It will infer 'MapTile*'. Or, if you forget the , then it will infer 'MapTile' and do the copy that I want to avoid. So it might be slightly more error-prone this way. 2. Use of a template function, allowing f() to take any type, not just MapTile. Interestingly you're passing MapTile*, AND the parameter is ref, so f() could change the pointer itself for the caller if it wanted to! Also, if you called f() elsewhere with just a MapTile, you'd have two copies if the function kicking around. So it saves us having to write the *, but at the expense of some messiness. (Also prevents a lot of the compile-time checks for f() from happening until f() is used.) At least that's assuming D templates are like C++ ones. I haven't read up on D templates yet. :) So unfortunately, neither solution really solves the problem. I suspect 'ref' for local variables could be added, and hasn't because it didn't figure in the specific use cases that someone had in mind when implementing it for parameters and 'foreach' variables. But it's also possible that (unlike in Java) local variables can do stuff that parameters can't (which I don't know about), which makes it impossible to allow 'ref' ones without invalidating a compile-time check or something. Hence why I was asking. :) Anyway, I hope I've been able to help a bit with your own D adventure :) Ben :) On 08/01/2012 19:27, simendsjo wrote: I got something working, but only when using templates. Take the following with a grain of salt as I'm a newbie myself. struct MapTile { string id; } enum w = 80, h = 25; MapTile[w*h] map; ref MapTile getTile(int x, int y) { return map[y*w+x]; } void f(T)(ref T tile) { tile.id = f(); } void g(ref MapTile tile) { tile.id = g(); } void main() { // You can use auto ref return to set values directly getTile(10,10).id = a; assert(getTile(10,10).id == a); // And using templated ref arguments, you can pass by reference // note that I need to take the reference even when // using auto ref return auto tile = getTile(1,1); f(tile); assert(tile.id == f()); // But you'll need a dereference if not using a template g(*tile); assert(tile.id == g()); assert(getTile(1,1).id == g()); }
Re: Ref local variables?
There are two things going on in your example: 1. Use of 'auto' where I'm currently having to write 'MapTile*' and wanted to write 'ref MapTile'. It will infer 'MapTile*'. Or, if you forget the , then it will infer 'MapTile' and do the copy that I want to avoid. So it might be slightly more error-prone this way. 2. Use of a template function, allowing f() to take any type, not just MapTile. Interestingly you're passing MapTile*, AND the parameter is ref, so f() could change the pointer itself for the caller if it wanted to! Also, if you called f() elsewhere with just a MapTile, you'd have two copies if the function kicking around. So it saves us having to write the *, but at the expense of some messiness. (Also prevents a lot of the compile-time checks for f() from happening until f() is used.) At least that's assuming D templates are like C++ ones. I haven't read up on D templates yet. :) So unfortunately, neither solution really solves the problem. I suspect 'ref' for local variables could be added, and hasn't because it didn't figure in the specific use cases that someone had in mind when implementing it for parameters and 'foreach' variables. But it's also possible that (unlike in Java) local variables can do stuff that parameters can't (which I don't know about), which makes it impossible to allow 'ref' ones without invalidating a compile-time check or something. Hence why I was asking. :) Anyway, I hope I've been able to help a bit with your own D adventure :) Ben :) On 08/01/2012 19:27, simendsjo wrote: I got something working, but only when using templates. Take the following with a grain of salt as I'm a newbie myself. struct MapTile { string id; } enum w = 80, h = 25; MapTile[w*h] map; ref MapTile getTile(int x, int y) { return map[y*w+x]; } void f(T)(ref T tile) { tile.id = f(); } void g(ref MapTile tile) { tile.id = g(); } void main() { // You can use auto ref return to set values directly getTile(10,10).id = a; assert(getTile(10,10).id == a); // And using templated ref arguments, you can pass by reference // note that I need to take the reference even when // using auto ref return auto tile = getTile(1,1); f(tile); assert(tile.id == f()); // But you'll need a dereference if not using a template g(*tile); assert(tile.id == g()); assert(getTile(1,1).id == g()); }